Директивы AngularJS атрибуты доступа от контроллера
Я пытаюсь получить доступ к атрибутам директивы в функции контроллера. Однако к моменту моего доступа к нему он undefined. Я заметил, что если я делаю простой таймер, он работает. Есть ли способ выполнить код только после того, как директива и его области готовы и установлены для использования?
Я сделал с ним скрипку. Убедитесь, что консоль открыта. http://jsfiddle.net/paulocoelho/uKA2L/1/
Вот код, который я использую в скрипте:
<div ng-app="testApp" >
<testcomponent text="hello!"></testcomponent>
</div>
var module = angular.module('testApp', [])
.directive('testcomponent', function () {
return {
restrict: 'E',
template: '<div><p>{{text}} This will run fine! </p></div>',
scope: {
text: '@text'
},
controller: function ($scope, $element) {
console.log($scope.text); // this will return undefined
setTimeout(function () {
console.log($scope.text); // this will return the actual value...
}, 1000);
},
link: function ($scope, $element, $attrs) {
console.log($scope.text);
setTimeout(function () {
console.log($scope.text);
}, 1000);
}
};
});
Ответы
Ответ 1
Что работает, если вы установили
scope.text = $attrs.text;
внутри функций связывания и контроллера. Это будет работать только на начальном этапе, поскольку нет двухсторонней привязки. Вы можете использовать $attrs.observe, хотя.
Смотрите скрипту: http://jsfiddle.net/JohannesJo/nm3FL/2/
Ответ 2
В изолированной области доступ к локальному свойству видимости с параметром '@' недоступен в функции связывания. Как уже упоминалось @remigio, такие локальные свойства области undefined
в этой точке. $attrs. $observ() или $scope. $aus() необходимо использовать для асинхронного получения значения (интерполированного).
Если вы передаете постоянное значение в атрибуте (т.е. не требуется интерполяция, то есть значение атрибута не содержит {{}} s), нет необходимости в '@' или $observer или $смотреть. Вы можете использовать $attrs. attribute_name один раз, как предлагает @hugo, или если вы передаете число или логическое значение, и вы хотите получить правильный тип, вы можете использовать $scope. $Eval ($ attrs. attribute_name).
Если вы используете '=' для привязки свойства локальной области к свойству родительской области, значение свойства будет доступно в функции связывания (нет необходимости в $watch или $watch или $eval).
Ответ 3
Так как Angular 1.3, вы можете использовать bindToController
. Вот пример того, как я его использую. Здесь я добавляю атрибут в область видимости, а затем использую bindToController
для использования внутри контроллера:
var module = angular.module('testApp', [])
.directive('testcomponent', function () {
return {
restrict: 'E',
template: '<div><p>{{text}} This will run fine! </p></div>',
scope: {
text: '@text'
},
controller: function () {
console.log(this.text);
},
controllerAs: 'vm',
bindToController: true
};
});
Angular 1.3 вводит новое свойство в определение директивы объект, называемый bindToController, который делает именно то, что он говорит. когда установлен в true в директиве с изолированной областью, которая использует controllerAs, свойства компонентов привязаны к контроллеру, а не к объем. Это означает, что Angular гарантирует, что, когда контроллер инстанцированные, начальные значения изолированных привязок областей доступный на этом, и будущие изменения также автоматически доступны.
Ответ 4
Вместо использования $scope
для получения значения атрибутов директивы лично я предпочитаю использовать $attrs
для функции controller
или просто attrs
в третьем параметре функции link
. У меня нет проблем при получении значения атрибутов из controller
, следуя коду без таймаута:
var module = angular.module('testApp', [])
.directive('testcomponent', function () {
return {
restrict: 'E',
template: '<div><p>{{text}} This will run fine! </p></div>',
scope: {
text: '@text'
},
controller: ['$scope','$attrs', function ($scope, $attrs) {
console.log($attrs.text); // just call to the $attrs instead $scope and i got the actual value
$scope.text = $attrs.text; //assign attribute to the scope
}]
};
});
Ответ 5
Функция связи вызывается перед циклом $digest, в этот момент переменными области видимости являются undefined. Посмотрите эту главу и этот другой, чтобы понять, как ссылка функция работает. Вы используете только функцию ссылок, чтобы определять часы и/или поведение для директивы, а не манипулировать моделью, это делается в контроллерах.
Ответ 6
Если вы получаете доступ к этому значению из своей директивы для вставки в свое представление с помощью директивы, вы можете получить доступ к этому атрибуту, используя $compile api и сделать что-то вроде этого
var string = "<div> " + scope.text + "</div>";
$compile(string)(scope, function(cloned, scope){
element.append(cloned);
});