2015-10-17 4 views
0

Мы имеем следующий директиву внедрен:Angularjs связывание приоритета

angular.module('app', []) 
 
    .directive('dIsolatedWorks', function() { 
 
    return { 
 
     scope: { 
 
     prop: '=' 
 
     }, 
 
     template: '<span>{{name}}: {{prop}}</span>', 
 
     link: function(scope) { 
 
     scope.name = 'isolated'; 
 
     scope.prop = 'link'; 
 
     } 
 
    }; 
 
    }) 
 
    .directive('dIsolated', function() { 
 
    return { 
 
     scope: { 
 
     prop: '@' 
 
     }, 
 
     template: '<span>{{name}}: {{prop}}</span>', 
 
     controller: function($scope) { 
 
     $scope.prop = 'controller'; 
 
     }, 
 
     link: function(scope) { 
 
     scope.name = 'isolated'; 
 
     scope.prop = 'link'; 
 
     } 
 
    }; 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="app"> 
 
    <div d-isolated-works prop="attribute"></div> 
 
    <div d-isolated prop="attribute"></div> 
 
</div>

На самом деле в процессе реализации, я был уверен, что назначение на scope.prop поля изменит переменное, и она будет отображаться как 'link', не 'attribute'. Но в настоящее время мы видим, что реальное значение будет isolated: attribute. Однако его можно просто устранить, изменив назначение строки на назначение объекта.

Можете ли вы объяснить такое поведение?

ответ

0

Таким образом, после исследования angularjs код для ответа я нашел правильный - согласно angular.js v1.3.20 мы имеем следующие строки кода в связывая функцию для @ атрибутов (строка 7698):

 case '@': 
      attrs.$observe(attrName, function(value) { 
       isolateBindingContext[scopeName] = value; 
      }); 
      attrs.$$observers[attrName].$$scope = scope; 
      if (attrs[attrName]) { 
       // If the attribute has been provided then we trigger an interpolation to ensure 
       // the value is there for use in the link fn 
       isolateBindingContext[scopeName] = $interpolate(attrs[attrName])(scope); 
      } 
      break; 

В соответствии с этим код

  1. Angularjs регистрирует $ наблюдателя для атрибута (evalAsync, таким образом, он будет выполнен после того, как конец кода цепи)
  2. Значение правильно распространяется от атрибута и таким образом мы увидим его значение в функции связывания
  3. Функция связывания распространяется со значением атрибута.
  4. Связывание функция изменяет проп значение и завершает свою работу
  5. выполнения возвращается к функции $ наблюдателя (потому что он должен выполнить по крайней мере один раз)
  6. $ наблюдателя выполняется, и он изменяет значение обратно значение атрибута

в результате можно сказать, что использование строки переплетены Params в теле директивы разрешается только только для чтения значения до тех пор, пока не будет обернут в блок тайм-аута (или любой другой с отсроченным исполнением)

0

Я считаю, что параметры в области выделения связывают ПОСЛЕ фазы связывания. Вот почему вы получаете значение, переданное через атрибут «prop», а не тот, который вы задали в функции ссылок.

Не мог найти в документах, как я сказал (https://docs.angularjs.org/guide/compiler), но сделал небольшой эксперимент, который доказал это.

Check скрипка - Я только инициировано свойство атрибута «» в родительской области и «dIsolatedWorks» работала похожа на «dIsolated»

<div ng-app="app"> 
    {{attribute = 'hello world';}} 

    <div d-isolated-works prop="attribute"></div> 
    <div d-isolated prop="attribute"></div> 
</div> 

http://jsfiddle.net/ndfqruxf/

Причину, почему директива «dIsolatedWorks» работал, как вы ожидать, потому что на нем была настроена двухсторонняя привязка ('='), но в родительской области с атрибутом 'attribute' не было переменной. Поэтому директива dIsolatedWorks инициировала переменную.

+0

Работа с атрибутом как параметр не является параметром, как при использовании оператора @ i t определяется как строка, но не переменная. Фактически параметры не могут быть назначены после компоновки, так как вы можете свободно работать с ними в блоке связывания. Проблема в том, что значение prop переназначается каким-то образом – nesteant

1

Незначительные дает изменение же результатов как с префиксами = и @

angular.module('app', []) 
 
.directive('dIsolatedWorks', function() { 
 
return { 
 
    scope: { 
 
     prop: '=' 
 
    }, 
 
    template: '<span>{{name}}: {{prop}}</span>', 
 
    link: function (scope) { 
 
     scope.name = 'isolated'; 
 
     scope.prop = 'link'; 
 
    } 
 
}; 
 
}) 
 
.directive('dIsolated', function ($timeout) { 
 
return { 
 
    scope: { 
 
     prop: '@' 
 
    }, 
 
    template: '<span>{{name}}: {{prop}}</span>', 
 
    controller: function ($scope) { 
 
     $scope.prop = 'controller'; 
 
    }, 
 
    link: function (scope, element, attr) { 
 
     scope.name = 'isolated'; 
 
     $timeout(function(){ }); 
 
     $timeout(function(){ 
 
      console.log('Still I found attrib value: ',scope.prop); 
 
      
 
      scope.prop = 'link'; // this will change it 
 
      }); 
 
     //scope.prop = 'link'; 
 
    \t 
 
    } 
 
}; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="app"> 
 
    <div d-isolated-works prop="attribute"></div> 
 
    <div d-isolated prop="attribute"></div> 
 
</div>

Но концептуально

@ связывание для передачи строк. Эти строки поддерживают выражения {{}} для интерполированных значений. Например: . Интерполированное выражение оценивается в соответствии с родительской областью директивы.

= обязательный для двухсторонней привязки модели. Модель в родительской области связана с моделью в изолированной области действия директивы. Изменения одной модели влияют на другую, и наоборот.

Сохраняя выше концепции в виду, анализ:

1 - когда мы определяем сферу с префиксом «@» шаблон всегда получает значение из ATTRIB (так link сферы.проп не влияет ничего)

2 - затем создает scope и присваивает значение строки ATTRIB к нему

Но

3 -, когда второй переваривать цикл будет работать (на ng-click или ng-model или $timeout) Будет изменено значение

4 - se e $timeout в вышеуказанном кодексе для понимания (Запустить его!)

Счастливая помощь!

+0

Проблема не в дайджесте. Поскольку ng-click или timeout будут работать только с переназначением свойства. Как вы правильно упоминали в 2-ом пункте: создается область и атрибут присваивается prop. Но концептуальная функция ссылок запускается после этого действия, поэтому я должен увидеть новую опору, но я все еще вижу значение атрибута – nesteant