Zrozumienie parametrów kontrolera Angular.js.

80

Dopiero zaczynam uczyć się Angular.js i patrzyłem na project.js w przykładzie „Wire up a Backend” na stronie domowej Angular .

Nie mam pojęcia co do parametrów w funkcjach kontrolera:

function ListCtrl($scope, Projects) {
  ... 
}   

function CreateCtrl($scope, $location, $timeout, Projects) {
  ... 
}

function EditCtrl($scope, $location, $routeParams, angularFire, fbURL) {
   angularFire(fbURL + $routeParams.projectId, $scope, 'remote', {}).
   then(function() {
     ...
   });
}  

Te funkcje kontrolera są wywoływane w routeProvider, ale żaden z parametrów nie jest podawany.

$routeProvider.
  when('/', {controller:ListCtrl, templateUrl:'list.html'}).
  when('/edit/:projectId', {controller:EditCtrl, templateUrl:'detail.html'}).
  when('/new', {controller:CreateCtrl, templateUrl:'detail.html'}).
  otherwise({redirectTo:'/'});
});

Jedyną rzeczą, którą udało mi się znaleźć tak daleko, że być może wyjaśnia, co dzieje się „Kontrolery Injecting Usługi na” , co tłumaczy $location, $timeoutale nie Parametry metody angularFirei fbURL.

Moje konkretne pytania to:

  1. Jakie mogą być parametry sterownika?

  2. Gdzie są wywoływane funkcje kontrolera wraz z ich parametrami? Lub parametry nie są wywoływane, ale są po prostu związane z kontrolerem, gdzie skojarzenie występuje z dużą ilością magii Angular.js (jeśli tak, czy mogę zobaczyć kod źródłowy na githubie)?

  3. Gdzie jest angularFirezdefiniowane?

  4. W jaki sposób fbURLparametr jest powiązany z:

    angular.module('project', ['firebase']).
        value('fbURL', 'https://angularjs-projects.firebaseio.com/').
        factory ...
    
  5. Czy jest jakieś miejsce, gdzie mogę zobaczyć wszystkie usługi, na przykład $locationa $timeout, że angularjs zapewnia? (Próbowałem znaleźć listę, ale nie udało mi się).

Alice
źródło
5. Aby zobaczyć listę wszystkich wbudowanych usług, filtrów, dyrektyw zawartych w Angular, spójrz na API: docs.angularjs.org/api
jpmorin
1
4. Jak zdajesz się rozumieć, parametry kontrolera są wprowadzane przez kąt z definicji kontrolera. Angular przeszuka wszystkie zarejestrowane usługi i spróbuje znaleźć dopasowanie do określonej nazwy parametru i wstrzyknie odpowiednią usługę!
jpmorin
3. Podczas definiowania modułu projektu uwzględniono również zależność modułu Firebase. Wewnątrz modułu firebase musi istnieć usługa angularFire, taka jak poprzednia fbURL.
jpmorin
1
2. Oto właściwy sposób zdefiniowania kontrolera: angular.module('project').controller('EditCtrl', ['$scope', '$location', '$routeParams', 'angularFire', 'fbURL', function($scope, $location, $routeParams, angularFire, fbURL) { ... } ]);W ten sposób najpierw ustawiasz nazwę usług, które chcesz wstrzyknąć, a następnie, jeśli chcesz, nadasz im inną nazwę. W rzeczywistości jest to obowiązkowe, jeśli chcesz później zminimalizować swój kod kątowy (ponieważ minimalizacja zmieni nazwy zmiennych, angular musi nadal być w stanie znaleźć nazwy usług).
jpmorin
1
@jpmorin po prostu dodaj swoje komentarze jako odpowiedź, wszystkie są poprawne.
toxaq

Odpowiedzi:

152
  • Jakie mogą być parametry sterownika?

    Parametry kontrolera to zależności , które są wstrzykiwane przez usługę wtryskiwacza AngularJS. Mogą być wszystkim. Ale zwykle są to usługi, które będą używane wewnątrz kontrolera.

  • Gdzie są wywoływane funkcje kontrolera wraz z ich parametrami?

    Kontrolery, a także dyrektywy, filtry, usługi i wiele innych rzeczy w AngularJS to funkcje . Jednak struktura zarządza wieloma określeniami, kiedy i jak te funkcje są wywoływane.

    To, co nazywasz powiązanymi rzeczami, ma nazwę: zależność , jak wspomniano powyżej. To, co nazywacie magią, to mechanizm wstrzykiwania zależności AngularJS w akcji.

    Kiedy te funkcje (sterowniki i inne) są wywoływane przez wtryskiwacz, odczytuje nazwy parametrów (na przykład: $scopelub $httplub angularFire) i wyszukuje zarejestrowaną usługę o tej nazwie, która jest następnie podawana jako parametr podczas wywoływania funkcji.

    To jest proste. Istnieje kilka sposobów instruowania o swoich „zależnościach” (parametrach zarządzanych przez wtryskiwacz) od wtryskiwacza.

    Gdy po prostu zadeklarujesz swoją funkcję jako function myCtrl($scope) {}, iniektor będzie mógł znaleźć $scopeusługę na podstawie nazwy parametru. Ale jeśli zminimalizujesz kod JavaScript, wtryskiwacz nie będzie już mógł znaleźć usługi, ponieważ nazwa parametru zostanie zmieniona na mniejszy ciąg, na przykład „a” lub „x”. Aby uniknąć tego problemu, można określić nazwę usługi do wstrzyknięcia za pomocą notacji tablicowej . W takim przypadku możesz zadeklarować swoją funkcję w następujący sposób:myCtrl = ['$scope', function($scope) {}]

    W świecie AngularJS zobaczysz wiele zastosowań notacji tablicowej . Teraz zaczynasz to rozumieć. Możesz nawet wstrzyknąć $scopei angularFireużywać ich z innymi nazwami w swojej funkcji (zmiana nazwy nie jest zalecana - ten przykład służy do celów edukacyjnych): ['$scope', 'angularFire', function(skop, af) {}]- w ten sposób wewnątrz funkcji możesz użyć $ scope jako "skop" i angularFire jako „af”. Zamówienie usługi opisane w tablicy odpowiada kolejność parametrów.

Inny przykład:

var myController = ['$scope', '$resource', '$timeout',
    function($scope, $resource, $timeout) {
        // this controller uses $scope, $resource and $timeout
        // the parameters are the dependencies to be injected
        // by AngularJS dependency injection mechanism
    }
];
  • Gdzie zdefiniowano angularFire?

    W module firebase .

    Jak już wiesz, wtryskiwacz wstrzyknie wszystko, o ile ma zarejestrowaną nazwę tej „rzeczy” i jest ona dostępna w swoich rejestrach. Jeśli istnieje „usługa” o tej nazwie , jest w stanie ją zapewnić .

    Jak więc zbudowana jest name => stufflista, której używa wtryskiwacz?

    Moduł jest odpowiedzią. Moduł jest niewiele więcej niż listy name => stuff. Znajduje się w module, w którym rejestrujesz usługi, fabryki, filtry, dyrektywy i nie tylko.

    Przyjrzyj się uważnie metodom Module w oficjalnej dokumentacji ... prawie wszystkie z nich otrzymująjako parametry: nazwę i jakieś " rzeczy " (gdzie "rzeczy" to prawie zawsze funkcja definiująca albo kontroler, albo fabrykę albo dyrektywę ). To wszystko będzie możliwe do wstrzyknięcia pod określoną nazwą .

    Usługi AngularJS, takie jak „$ timeout”, „$ http” i inne są dostępne domyślnie, ponieważ moduł ng jest już załadowany przez framework.

    Aby skorzystać z dodatkowych usług, musisz załadować / wymagać modułu . To właśnie robisz z ngRouter , firebase , itp ... Po załadowaniu modułu jego zarejestrowane rzeczy są dostępne do wstrzyknięcia w twoim module / aplikacji.

Zobaczmy przykład krok po kroku:

// An empty module:
var module = angular.module('myModule', []);

// Now, adding an "injectable" constant: 
module.constant('niceStuff', { blip: 'blop', blup: 307 });

// We could add a service:
module.service('entityManager', ['$http', function($http){  }]);

// and so on... if I wanted to use "$resource" instead of "$http"
// in the entityManager service above...
// ...I would need to require the ngResource when creating the module above,
// like this: var module = angular.module('myModule', ['ngResource']);
// because "$resource" is not available by default

// NOW, anywhere else, since the code above already ran
// I can use those NAMES as dependencies like this:

// We are creating another module now:
var koolModule = angular.module('km', ['myModule']);
// Note that I am requiring the previous module through its registered name

// Now, anything I've declared in that module
// - just like "ng" (by default) and "firebase" (required) does -
// is available for "injection"!!!

koolModule.controller('koolController',
    ['niceStuff', 'entityManager', function(niceStuff, entityManager) {
        console.log(niceStuff.blip);      // 'blop'
        console.log(niceStuff.blup + 10); // 317
    }]
);

W ten sposób stają się dostępne rzeczy z Firebase, takie jak angularFire! Co my zrobiliśmy? Najpierw stworzyliśmy „myModule” i zarejestrowaliśmy w nim NAMED. Później wymagaliśmy "myModule" dla naszego "koolModule" - a te NAMES były już dostępne na name => stuffliście wtryskiwaczy .

  • W jaki sposób połączony jest fbURL w parametrze

    Jak właśnie widzieliśmy, większość metod modułowych po prostu rejestruje rzeczy - nadaje im nazwy, aby można je było później wstrzyknąć i / lub użyć w tych nazwach.

    Po module.value('fbURL', 'https://angularjs-projects.firebaseio.com/')wywołaniu fbURL (i określona wartość) jest rejestrowany na name => stuffliście ... w tym przypadku nazwa to „fbURL”, a wartość / stuff to ciąg adresu URL - ale może to być wszystko!

  • Czy jest miejsce, w którym mogę zobaczyć wszystkie usługi, np. $ Location i $ timeout, które zapewnia Angular.js?

    Tak, odniesienie do API: http://docs.angularjs.org/api/

    Zwróć uwagę, jak nawigacja po lewej stronie jest zorganizowana ... według modułów ! Najpierw moduł ng z mnóstwem dyrektyw, usług, filtrów itp. Następnie poniżej pozostałe moduły (ngRoute, ngResource, ngMock itd.), Z których każdy zawiera własne usługi, instalatory lub dyrektywy ...

Dzięki za możliwość podzielenia się tymi przemyśleniami. Pisanie ich sprawiało mi przyjemność.

J. Bruni
źródło
4
Dziękuję Ci! Dobre wyjaśnienie, co i dlaczego.
Kevin Shea,
4
Niejawne zachowanie oparte wyłącznie na obecności nazwanego parametru jest poza nieintuicyjne i jest absolutnie nienawistne, ale dzięki za świetną odpowiedź.
jarmod
1
@jarmod, dokładnie tak myślę - niepokojące jest przejście przez samouczek AngularJS „phonecat” bez wcześniejszego obejrzenia tego postu!
Monkpit
1
"To jest proste." NIE.
J. Dimeo,
2
Niesamowite wyjaśnienie. W niektórych samouczkach wiele rzeczy jest uważanych za oczywiste. „Po prostu wpisz to w ten sposób i działa”. Muszę wiedzieć, jak i dlaczego, a to wiele na to odpowiada. Dziękuję Ci bardzo za Twój czas!
John Carrell
1

Po pierwsze świetna robota przy wyborze tego frameworka. To jest najlepsze. Te zmienne, które widzisz ze znakiem $, są wstrzykiwane i stanowią część standardowego środowiska. Usługi te znacznie ułatwią Ci życie. Najlepszym sposobem myślenia o kontrolerach są arkusze skryptów. Pomagają oddzielić kod. Nie myśl o nich jak o metodach. Te zmienne, które widzisz, takie jak $ timeout i $ scope to usługi, które przydadzą się, gdy będziesz potrzebować pewnych rzeczy do zrobienia. Cała dokumentacja frameworka znajduje się pod adresem http://docs.angularjs.org/api/, ale zacząłbym od tego samouczka http://docs.angularjs.org/tutorial/ .

Pożar kątowy nie jest częścią ramy. Jest to kolejna usługa, która wykorzystuje strukturę do tworzenia potężnej sieci rozproszonej w czasie rzeczywistym. Po załadowaniu angularfirejs jest dostarczana z usługą, która jest następnie wstrzykiwana jako parametr, który widzisz.

Odpowiadając na drugie pytanie, parametry, które przekazujesz, mogą być dowolne, o ile wykonujesz odpowiednią usługę. Skorzystaj z tego, aby utworzyć własny parametr dla kontrolerów: http://docs.angularjs.org/guide/dev_guide.services.creating_services

fbURL to tylko zmienna, którą możesz utworzyć, a kod, który umieściłeś w swoim pytaniu, to po prostu instrukcja, jak to zrobić.

Angularjs nie jest typem frameworka, którego można się nauczyć, patrząc na jego ofertę. Po prostu dlatego, że oferuje wszystko. Wszystko, co możesz wnieść do stworzenia świetnej aplikacji. Zamiast tego powinieneś skupić się na zapytaniu Google, jak rozwiązać problem z angularem.

Zobacz także filmy na youtube. Znajdziesz kilka świetnych.

Pbrain19
źródło
1

Zgodnie z komentarzem toxaq, oto komentarz jako odpowiedź

  1. Jakie mogą być parametry sterownika?

    Mogą to być głównie usługi, fabryki, wartości, stałe itp., Które zdefiniowałeś gdzieś przed LUB używając funkcji rozwiązywania w definicji trasy.

  2. Gdzie są wywoływane funkcje kontrolera wraz z ich parametrami?

    Oto właściwy sposób zdefiniowania kontrolera:

    angular.module('project').controller('EditCtrl', [
        '$scope', 
        '$location', 
        '$routeParams', 
        'angularFire', 
        'fbURL', 
        function($scope, $location, $routeParams, angularFire, fbURL) { 
            ... 
        } 
    ]); 
    

    W ten sposób najpierw ustawisz nazwę usług, które chcesz wstrzyknąć, a następnie, jeśli chcesz, nadasz im inną nazwę. W rzeczywistości jest to obowiązkowe, jeśli chcesz później zminimalizować swój kod kątowy (ponieważ minimalizacja zmieni nazwy zmiennych, angular musi nadal być w stanie znaleźć nazwy usług).

  3. Gdzie zdefiniowano angularFire?

    Podczas definiowania modułu projektu uwzględniono również zależność modułu Firebase. Wewnątrz modułu firebase musi istnieć usługa angularFire, taka jak poprzednia fbURL.

  4. W jaki sposób fbURL w parametrze połączonym z

    Jak zdajesz się rozumieć, parametry kontrolera są wprowadzane przez kąt z definicji kontrolera. Angular przeszuka wszystkie zarejestrowane usługi i spróbuje znaleźć dopasowanie do określonej nazwy parametru i wstrzyknie odpowiednią usługę!

  5. Czy jest miejsce, w którym mogę zobaczyć wszystkie usługi, np. $ Location i $ timeout, które zapewnia Angular.js?

    Listę wszystkich wbudowanych usług, filtrów i dyrektyw zawartych w Angular można znaleźć w API: http://docs.angularjs.org/api

jpmorin
źródło
1

Gdzie są wywoływane funkcje kontrolera wraz z ich parametrami?

Funkcje kontrolera są tworzone za pomocą dyrektywy ngController lub jeśli wspomniano o kontrolerze podczas tworzenia trasy przy użyciu $routeProvider. AngularJS robi to bezpośrednio za Ciebie i wstrzykuje parametry, które zdefiniowałeś na swoim kontrolerze za pomocą DI.

DI działa dopasowując nazwy (lub czasami kolejność) parametrów. Więc $scopeotrzyma aktualny zakres, $httpotrzyma usługę http

Chandermani
źródło