Подтвердить что ты не робот

Директивы 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);
        }
    };
});
4b9b3361

Ответ 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);
});