Пытаясь понять мои собственные директивы AngularJS, у меня есть пример, который делает все, что мне нужно, но понимаю, что при заимствовании из разных примеров я теперь могу создать функциональность для представления директивы как в контроллере, так и в ссылке,
Кажется, я мог полностью избавиться от контроллера и просто поместить все в ссылку, или есть что-то, что я могу сделать с контроллером, который я не могу сделать со ссылкой?
http://jsfiddle.net/edwardtanguay/gxr49h96/6
.directive('itemMenu', function () {
var controller = function ($scope) {
var vm = this;
vm.addItem = function () {
$scope.add();
vm.items.push({
'kind': 'undefined',
'firstName': 'Joe',
'lastName': 'Newton',
'age': Math.floor(Math.random() * 60) + 20
});
};
// DOES THE SAME AS THE FUNCTION DEFINED BELOW IN LINK
// $scope.convertToInternal = function(item) {
// item.internalcode = 'X0000';
// item.kind = 'internal';
// };
};
return {
restrict: 'A',
scope: {
item: '=',
add: '&'
},
controller: controller,
controllerAs: 'vm',
bindToController: true,
template: '<div ng-include="getTemplateUrl()"></div>',
link: function (scope, element, attrs) {
scope.getTemplateUrl = function () {
switch (scope.item.kind) {
case 'external':
return 'itemMenuTemplateExternal';
case 'internal':
return 'itemMenuTemplateInternal';
default:
return 'itemMenuTemplateUndefined';
}
};
scope.convertToInternal = function(item) {
item.internalcode = 'X0000';
item.kind = 'internal';
};
},
};
})
Вы можете найти много водянистых тиранов о контроллере против ссылки, большинство из которых содержат информацию из документации компиляции компиляции.
Отвечая на вопрос напрямую,
контроллеры из других модулей/файлов могут быть подключены к директиве через Angular DI с controller: 'Controller'
controller
можно вводить зависимости, тогда как link
имеет фиксированный список аргументов и получает с помощью директивных зависимостей
controller
запускается до link
, поэтому он может подготовить область для связывания или перекомпиляции элемента при некоторых условиях ASAP
контроллер имеет this
, его внешний вид кода соответствует другому OOP-подобному ES5-коду, и методы могут быть легко перенесены между другими частями кода, например service
сервис или сторонний код
в результате контроллеры могут быть определены как классы ES2015 или TS.
директивному контроллеру может require
d дочерней директивой и обеспечивает удобное одностороннее взаимодействие между этими двумя
controller
использует bindToController: true
+ controllerAs: 'vm'
и реализует рецепт $scope.vm
(особенно полезный для борьбы с прототипным наследованием JS), сохраняя this
синтаксис
bindToController
объекта bindToController
предоставляет привязки атрибутов для унаследованной scope: true
scope, no more $attr.$observe
bindToController
объекта bindToController
обеспечивает дополнительную детализацию для выделенной области. Если есть определенные атрибуты, которые должны быть привязаны к контроллеру и доступны с require
, это можно сделать сейчас
Какой код идет к controller
а для link
- более тонкий вопрос.
Обычным является использование угловых контроллеров в качестве моделей представлений, как в MVVM (следовательно, соглашение controllerAs: 'vm'
), поэтому, если есть задание для контроллеров (т.е. привязка служб к значениям области или настройке наблюдателей за областью), их, оставьте остальные link
.
Поскольку $attrs
, $element
и $transclude
локальные зависимости должны быть введены в контроллер явно, один может считать это признаком, чтобы пропустить их ($scope
следует вводить для $scope.$
Methods, но мы просто проигнорируем этот факт),
Есть некоторые нерелигиозные проблемы, связанные с работой, которая должна выполняться по link
а не по controller
. require
d контроллеры не были доступны в самом контроллере, поэтому такое взаимодействие с директивой происходит по link
. Поскольку controller
запускается на более раннем этапе компиляции, чем link
, привязанные значения атрибутов пока не будут интерполированы, поэтому код, который зависит от этих значений области, переходит в link
. То же самое относится к другому DOM-связанному коду, он идет по link
по какой-либо причине.
Это в основном вопрос правильного стиля кода, а не реальной необходимости. Что касается кода в этом примере, вся информация о scope
является удобной для контроллера, я не думаю, что эта link
должна быть вообще.