Розуміння параметрів контролера Angular.js


80

Я тільки починаю вивчати Angular.js і я розглядав project.js у прикладі " Підключіть бекенд" на домашній сторінці Angular .

Мене бентежать параметри функцій контролера:

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() {
     ...
   });
}  

Ці функції контролера викликаються у routeProvider, але жоден з параметрів не вказаний.

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

Єдине , що я міг би знайти так далеко , що , можливо , пояснює , що відбувається це «Ін'єкція послуги в контролери» , що пояснює $location, $timeoutале не параметри методу angularFireі fbURL.

Мої конкретні запитання:

  1. Якими можуть бути параметри контролера?

  2. Де викликаються функції контролера з їх параметрами? Або параметри не викликаються, а лише речі, пов'язані з контролером, де асоціація відбувається з великою кількістю магії Angular.js (якщо так, чи можу я побачити вихідний код на github)?

  3. Де angularFireвизначено?

  4. Як fbURLпов’язано параметр in у:

    angular.module('project', ['firebase']).
        value('fbURL', 'https://angularjs-projects.firebaseio.com/').
        factory ...
    
  5. Чи є десь місце, де я можу бачити всі послуги, наприклад $locationі $timeout, що надає Angular.js? (Я намагався знайти список, але не вдалося.)


5. Щоб переглянути список усіх вбудованих служб, фільтрів та директив, що входять до Angular, подивіться на API: docs.angularjs.org/api
jpmorin

1
4. Як ви, мабуть, розумієте, параметри контролера вводяться кутовим з визначення контролера. Angular загляне у всі зареєстровані сервіси та спробує знайти відповідність із зазначеним іменем параметра та внести відповідну службу!
jpmorin

3. Визначивши модуль проекту, ви також включили залежність модуля firebase. Усередині модуля firebase повинна бути служба angularFire, як попередня fbURL.
jpmorin

1
2. Ось правильний спосіб визначення контролера: angular.module('project').controller('EditCtrl', ['$scope', '$location', '$routeParams', 'angularFire', 'fbURL', function($scope, $location, $routeParams, angularFire, fbURL) { ... } ]);Таким чином, ви спочатку встановлюєте назву служб, які ви хочете ввести, а потім надаєте цим службам іншу назву, якщо хочете. Насправді, це обов’язково, якщо ви хочете згодом мінімізувати свій кутовий код (оскільки мінімізація перейменує змінні, angular все одно повинен мати можливість знаходити імена служб).
jpmorin

1
@jpmorin просто додайте свої коментарі як відповідь, вони всі вірні.
toxaq

Відповіді:


152
  • Якими можуть бути параметри контролера?

    Параметри контролера - це залежності , які вводиться службою інжектора AngularJS. Вони можуть бути будь-якими. Але це, як правило, послуги, які будуть використовуватися всередині контролера.

  • Де викликаються функції контролера з їх параметрами?

    Контролери, а також директиви, фільтри, служби та багато іншого в AngularJS - це функції . Але фреймворк багато управляє тим, коли і як називаються ці функції.

    Те, що ви називаєте пов’язаним, має назву: залежність , як уже згадувалося вище. Те, що ви називаєте магією, - це діючий механізм введення залежності AngularJS .

    Коли інжектор викликає ці функції (контролери та інші), він зчитує імена параметрів (наприклад: $scopeабо $httpабо angularFire) і шукає зареєстровану службу з цим іменем, яка потім надається як параметр при виклику функції.

    Це просто. У вас є кілька способів проінструктувати про свої "залежності" (параметри, керовані інжектором) від інжектора.

    Коли ви просто оголосите свою функцію як function myCtrl($scope) {}, інжектор зможе знайти $scopeслужбу за назвою параметра. Але якщо ви зменшите код JavaScript, інжектор більше не зможе знайти службу, оскільки ім'я параметра буде змінено на менший рядок, наприклад "a" або "x". Щоб уникнути цієї проблеми, можна вказати назву служби, яку потрібно вводити, використовуючи позначення масиву . У цьому випадку ви оголосите свою функцію так:myCtrl = ['$scope', function($scope) {}]

    Ви побачите багато використання позначень масивів у світі AngularJS. Тепер ви починаєте це розуміти. Ви навіть можете вводити $scopeта angularFireвикористовувати їх з іншими іменами у своїй функції (зміна імені не рекомендується - цей приклад подається для навчальних цілей): ['$scope', 'angularFire', function(skop, af) {}]- таким чином, всередині функції ви можете використовувати $ scope як "skop" та angularFire як "af". Замовлення послуг в масиві відповідає порядку параметрів.

Інший приклад:

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
    }
];
  • Де визначається angularFire?

    У модулі firebase .

    Як ви вже зараз знаєте, інжектор буде впорскувати що завгодно, доки воно має назву "річ", зареєстровану та доступну в її записах. Якщо існує "послуга" з таким ім'ям , він може її надати .

    Як тоді складається цей name => stuffсписок, який використовує інжектор?

    Модуль - це відповідь. Модуль трохи більше , ніж список name => stuff. Це в модулі, де ви реєструєте служби, заводи, фільтри, директиви тощо.

    Уважно подивіться на методи модуля в офіційній документації ... майже всі вони отримують як параметри: ім'я та деякі " речі " (де "речі" майже завжди є функцією , що визначає або контролер, або завод, або директиву ). Усі ці "речі" стануть ін'єкційними за допомогою зазначеного імені .

    Послуги AngularJS, такі як "$ timeout", "$ http" та інші, доступні за замовчуванням, оскільки модуль ng вже завантажений фреймворком.

    Для отримання додаткових послуг вам потрібно завантажити / зажадати модуль . Це те, що ви робите з ngRouter , firebase тощо ... Завантажуючи модуль , його зареєстровані матеріали доступні для введення у ваш модуль / додаток.

Давайте подивимось покроковий приклад:

// 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
    }]
);

Ось як речі Firebase, такі як angularFire, стають доступними! Що ми зробили? По-перше, ми створили "myModule" та зареєстрували в ньому матеріали NAMED. Пізніше ми вимагали "myModule" для нашого "koolModule" - і ці НАЗВИ вже були доступні в списку інжекторів name => stuff.

  • Як пов'язаний fbURL у параметрі

    Як ми тільки що бачили, більшість методів модулів просто реєструють речі - даючи імена речам, щоб їх можна було вводити та / або використовувати через ці імена пізніше.

    При module.value('fbURL', 'https://angularjs-projects.firebaseio.com/')виклику fbURL (і задане значення) зареєстровано в name => stuffсписок ... в цьому випадку, назва «fbURL», а значення / матеріал рядок URL - але це може бути що завгодно!

  • Чи є місце, де я можу бачити всі послуги, наприклад $ location та $ timeout, які надає Angular.js?

    Так, посилання на API: http://docs.angularjs.org/api/

    Зверніть увагу на те, як навігація зліва організована ... за модулями ! По-перше, модуль ng з безліччю директив, служб, фільтрів тощо. Потім, нижче, інші модулі (ngRoute, ngResource, ngMock тощо), кожен з яких містить власні послуги, комплектуючі чи директиви ...

Дякую за можливість поділитися цими думками. Мені подобалося писати їх.


4
Дякую! Гарне пояснення того, що і чому.
Kevin Shea

4
Неявна поведінка, заснована виключно на наявності названого параметра, є неінтуїтивною і абсолютно ненависною, але дякую за чудову відповідь.
jarmod

1
@jarmod, мої думки точно - незрозуміло пройти підручник з AngularJS "phonecat", не бачивши цього повідомлення спочатку!
Monkpit

1
"Це просто". НЕ.
J. Dimeo

2
Чудове пояснення. У деяких підручниках є багато речей, що сприймаються як само собою зрозуміле. "Просто введіть так, і це працює". Мені потрібно знати, як і чому, і це багато на що відповіло. Щиро дякую за Ваш час!
Джон Каррелл,

1

По-перше, відмінна робота з вибору цієї системи. Це найкраще. Ті змінні, які ви бачите зі знаком $, вводяться та є частиною стандартного фреймворку. Ці послуги значно полегшать вам життя. Найкращий спосіб думати про контролери - це аркуші сценаріїв. Вони допомагають відокремити код. Не сприймайте їх як методи. Такі змінні, які ви бачите, такі як $ timeout & $ scope - це послуги, які стануть в нагоді, коли вам потрібні певні речі. Вся документація для фреймворку знаходиться на веб- сайті http://docs.angularjs.org/api/, але я б розпочав з цього підручника http://docs.angularjs.org/tutorial/ .

Кутовий вогонь не є частиною рамки. Це ще одна послуга, яка використовує структуру для створення потужної розподіленої мережі в режимі реального часу. Коли ви завантажуєте angularfirejs, він постачається зі службою, яка потім вводиться як параметр, який ви бачите.

Щоб відповісти на ваше друге запитання, параметри, які ви передаєте, можуть бути будь-якими, якщо ви зробите відповідну послугу. Будь ласка, зверніться до цього, щоб створити власний параметр для контролерів: http://docs.angularjs.org/guide/dev_guide.services.creating_services

fbURL - це просто змінна, яку ви можете створити, і код, який ви розмістили у своєму запитанні, - це просто інструкція, як це зробити.

Angularjs - це не той тип фреймворку, який ви можете навчитися, дивлячись на те, що він пропонує. Просто тому, що він пропонує все це. Все, що ви могли б принести, щоб зробити чудовий додаток. Натомість вам слід зосередитися на питанні google, як вирішити вашу проблему з angular.

Також перегляньте відео на YouTube. Ви знайдете кілька чудових.


1

Відповідно до коментаря toxaq, ось коментарі як відповідь

  1. Якими можуть бути параметри контролера?

    В основному це можуть бути послуги, фабрики, значення, константи тощо ..., які ви десь визначили до АБО, використовуючи вирішення у визначенні маршруту.

  2. Де викликаються функції контролера з їх параметрами?

    Ось правильний спосіб визначення контролера:

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

    Таким чином, ви спочатку встановлюєте назву служб, які ви хочете ввести, а потім надаєте цим службам іншу назву, якщо хочете. Насправді, це обов’язково, якщо ви хочете згодом мінімізувати свій кутовий код (оскільки мінімізація перейменує змінні, angular все одно повинен мати можливість знаходити імена служб).

  3. Де визначається angularFire?

    Визначивши модуль проекту, ви також включили залежність модуля firebase. Усередині модуля firebase повинна бути служба angularFire, як попередня fbURL.

  4. Як пов’язано fbURL у параметрі

    Як ви, мабуть, розумієте, параметри контролера вводяться кутовим з визначення контролера. Angular загляне у всі зареєстровані сервіси та спробує знайти відповідність із зазначеним іменем параметра та внести відповідну службу!

  5. Чи є місце, де я можу бачити всі послуги, наприклад $ location та $ timeout, які надає Angular.js?

    Список усіх вбудованих служб, фільтрів та директив, включених до Angular, можна переглянути в API: http://docs.angularjs.org/api


1

Де викликаються функції контролера з їх параметрами?

Функції контролера створюються за допомогою директиви ngController або якщо ви згадали контролер під час створення маршруту за допомогою $routeProvider. AngularJS робить це транзитно для вас і вводить параметри, які ви визначили на своєму контролері за допомогою DI.

DI працює, узгоджуючи імена (або кілька разів) параметрів. Так $scopeотримав би поточний обсяг, $httpотримав би послугу http

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.