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

AngularJS - доступ к изолированной области в функции директивной ссылки

Я пытаюсь настроить пользовательские директивы AngularJS.

У меня возникли проблемы с использованием (или пониманием...) изолированной области действия ссылки в директиве.

Вот код этой части моего приложения:

view.html

...
<raw-data id="request-data" title="XML of the request" data="request">See the request</raw-data>
...

request - это переменная, опубликованная в области viewCtrl, которая содержит xml-строку запроса.

rawData.js

directives.directive('rawData', function() {

    return {
        restrict : 'E',
        templateUrl : 'partials/directives/raw-data.html',
        replace : true,
        transclude : true,
        scope : {
            id : '@',
            title : '@',
            data : '='
        },
        link : function($scope, $elem, $attr) {
            console.log($scope.data); //the data is correclty printed
            console.log($scope.id); //undefined
        }
    };
});

сырой data.html

<div>
    <!-- Button to trigger modal -->
    <a href="#{{id}}Modal" role="button" class="btn" data-toggle="modal" ng-transclude></a>

    <!-- Modal -->
    <div id="{{id}}Modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="{{id}}Modal" aria-hidden="true">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
            <h3 id="myModalLabel">{{ title }}</h3>
        </div>
        <div class="modal-body">
            <textarea class="input-block-level" rows="10">{{ data }}</textarea>
        </div>
        <div class="modal-footer">
            <!-- <button class="btn" ng-click="toggleTagText('')">{{'cacher'}} l'image</button> -->
            <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">Fermer</button>
        </div>
    </div>
</div>

Я не понимаю, почему идентификатор показан в случае модальных всплывающих окон, но когда я пытаюсь его console.log(), его значение равно undefined.

Возможно, я ошибаюсь с изолированным значением области (= и @).

Спасибо за чтение.:)

4b9b3361

Ответ 1

Изолировать свойства области, связанные с @, не доступны сразу в функции связывания. Вам нужно использовать $observe:

$attr.$observe('id', function(value) {
   console.log(value);
});

Ваш шаблон работает правильно, потому что Angular автоматически обновляет выделение свойства scope id для вас. И когда он обновляется, ваш шаблон автоматически обновляется.

Если вы просто передаете строки, вы можете просто оценить значения один раз вместо использования привязки @:

link: function($scope, $elem, $attr) {
    var id    = $attr.id;
    var title = $attr.title
    console.log(id, title);
}

Однако в вашем случае, поскольку вы хотите использовать свойства в шаблонах, вы должны использовать @.

Если вы не использовали шаблоны, то @ полезно, когда значения атрибутов содержат {{}} – например, title="{{myTitle}}". Затем становится очевидной необходимость использования $observe: ваша функция связывания может что-то делать каждый раз, когда изменяется значение myTitle.

Ответ 2

Это намеренно и связано с порядком компиляции и разницей между "@" и "=".

Некоторые выдержки из это обсуждение в Google Groups с помощью входа в Misko:

@и = делать очень разные вещи. Один экземпляр значения атрибута (который может быть интерполирован), а другой обрабатывает значение атрибута как выражение.

@attrs не интерполируются до конца, поэтому они недоступны в время ссылки. Если вы хотите что-то сделать с ними в функции связи вам либо нужно вручную интерполировать $

Ответ 3

ну, ни один из ответов выше не упомянул один ключевой аспект, даже с '=', мне кажется, что вы не можете получить доступ к области внутри функции ссылок, как показано ниже,

scope: {
    data: '=',
},
link: function(scope, elem, attrs) {
    console.debug(scope.data); // undefined

но вы можете получить доступ к области во внутренней функции,

link: function(scope, elem, attrs) {
    scope.saveComment = function() {
        console.debug(scope.data);

так что мне кажется, что может появиться временное отставание, когда scope.data может быть доступен.