Использование функций из директивного контроллера в пределах функции связи той же директивы
Возможно, у меня есть фундаментальное непонимание того, как работают контроллеры директив, из того, что я понимаю, они используются в качестве своего рода API для доступа к другим директивам и контроллерам. Я пытаюсь заставить контроллер и функцию связи связываться внутри.
Например, я хотел бы иметь возможность устанавливать переменную через функцию контроллера, а затем использовать ее в функции ссылки:
var app = angular.module('test-app', []);
app.directive('coolDirective', function () {
return {
controller: function () {
this.sayHi = function($scope, $element, $attrs) {
$scope.myVar = "yo"
}
},
link: function(scope, el, attrs) {
console.log(scope.myVar);
}
}
});
Как я могу получить доступ к myVar или sayHi в функции ссылок? Или я просто полностью упустил точку?
Ответы
Ответ 1
Оба контроллера $scope (определенные в контроллере, а не в функции sayHi
) и ссылка scope
совпадают. Установка чего-либо в контроллере будет использоваться из ссылки или наоборот.
Проблема заключается в том, что sayHi
- это функция, которая никогда не запускается, поэтому myVar
никогда не устанавливается.
Так как sayHi
не входит в область действия, вам нужна ссылка на контроллер, и для этого вы можете добавить четвертый параметр следующим образом:
link: function(scope, element, attr, ctrl) {}
Тогда вы можете сделать ctrl.sayHi()
(Но опять же, те параметры sayHi
относятся к функции контроллера.)
Если вам когда-либо понадобится другой контроллер и все еще хочет использовать свою собственную директиву, вам также потребуется его потребовать. Поэтому, если этот coolDirective
должен получить доступ к контроллеру notCoolAtAll
, вы можете сделать:
require: ['coolDirective', 'notCoolAtAll']
Это сделает трюк. Функция link
получит тогда массив контроллеров в качестве четвертого параметра, и в этом случае первый элемент будет coolDirective
ctrl, а второй - notCoolAtAll
.
Вот небольшой пример: http://plnkr.co/edit/JXahWE43H3biouygmnOX?p=preview
Ответ 2
Переписывая код выше, он будет выглядеть примерно так:
var app = angular.module('test-app', []);
app.directive('coolDirective', function() {
return {
controller: function($scope) {
// bind myVar property to scope
$scope.myVar = 'yo';
// bind sayHi method to scope
$scope.sayHi = sayHi;
// abstracting out the sayHi function
function sayHi() {
console.log($scope.myVar);
}
},
link: function(scope, el, attrs) {
// execute the sayHi function from link
scope.sayHi(); // "yo" in console
}
};
});
Удачи.