2-х сторонняя директива по связыванию данных

Я смущен о 2-х сторонней привязке данных в угловых. Посмотри на код! var bah может получить доступ к родительскому объекту $scope.something но когда я нажимаю кнопку, значение в контроллере меняется на false но не в директиве. в чем дело? это ошибка?

как это решить? спасибо, чтобы помочь мне, надеюсь, вы, пожалуйста, напишите пример или ссылки ref

HTML

<div ng-controller="myController">
  show me something {{ something }} <br>
  <button ng-click="toggleSomething"><button>

  <!-- this is a canvas -->
  <my-directive></my-directive>
</div>

JS

angular.module('fooBar',[]).controller('myController', ['$scope', function($scope) {
   // this is the something
   $scope.something = true;

   $scope.toggleSomething = function(){
     if($scope.something) { 
       $scope.something = false 
     } else { 
       $scope.something = true 
     }
   }

}]).directive('myDirective', function(){
  return {
    template: '<canvas width="500px" height="500px"></canvas>',
    link: function(scope, el, attr) {
      //how to access that 'something'
      var bah = scope.$parent.something;
    }
  };
});

ОБНОВЛЕНИЕ Действительно, спасибо вам всем. особенно тебе @immirza

мне так жаль, я не могу ответить вам один за другим. это просто добавить $parent

//how to access that 'something'
var bah = scope.$parent.something

3 ответа

Решение

Я установил планку с вашим кодом и добавил двустороннюю привязку к директиве. Вы можете увидеть это на PLNKR

angular.module('fooBar',[]).controller('myctr', ['$scope', function($scope) {
   // this is the something
   $scope.something = true;

   $scope.toggleSomething = function(){
     if($scope.something) { 
       $scope.something = false 
     } else { 
       $scope.something = true 
     }
   }

}]).directive('myDirective', function(){
  return {
    //changed canvas to span so for simplixity.
    template: '<span width="500px" height="500px">{{blah}} --- {{ dsomething }}</span>',
    scope: { dsomething: "=" },
    link: function(scope, el, attr) {

      //watching $parent.variable is not recommonded as it makes your
      //directive less reusable and forces who ever wants to use your
      //directive to create the variable.  dsomething will just update
      //nicely w/o any code in this link function. the code below is just to demonstrate
      //how to get it done by using $watch with $parent scope.

      //how to access that 'something'
      if(!scope.dsomething){
        scope.dsomething = "something";
      }

      //because blah is a local variable and not a two-way binding variable
      //we need to use $watch to update the value.
      //you can use "dsomething" instead of "$parent.something"
      //
      scope.$watch("$parent.something", function(newVal, oldVal){
         scope.blah = newVal;
      })
    }
  };
});

Вы можете использовать свою директиву как:

<div ng-controller="myctr">
  show me something {{ something }}             <br />
  <button ng-click="toggleSomething()">Update Something</button>
  <button>
    <!-- this is a canvas -->
    <my-directive dsomething="something"></my-directive>
  </button>
</div>

Обратите внимание на ng-click="toggleSomething()". это вызов функции, не передающий функцию. ng-click="toggleSomething" не будет работать.

Вы можете получить прямой доступ к $scope.something в myDirective без использования $parent потому что директива shared scope

и на ваш вопрос, если вы пытаетесь обнаружить something изменения внутри директивы вы не можете просто поставить console.log($scope.something) и проверьте, потому что он выполняется только один раз, и после щелчка он не будет печатать снова, это не значит, something не меняется внутри directive,

а также вы сделали ошибку в ng-click лайк ng-click="toggleSomething" так должно быть ng-click="toggleSomething()" так как вы вызываете функцию, а не просто переменную.

вот ДЕМО

я положил <h1> ... {{ something }}</h1> внутри шаблона директивы, чтобы показать, что что-то работает, как и ожидалось, внутри директивы.

Пройдите эту превосходную серию директив

Проблема в том, что вы не понимаете, что такое двусторонняя привязка данных, в основном любой элемент, который two way bound с директивой может быть обновлено контроллером или директивой, а другая немедленно увидит это изменение в ней.

Когда вы получаете доступ к нему с помощью $parent вы принудительно читаете значение в вашей директиве, и ничего более, никто не говорит директиву для переоценки var bah = scope.$parent.something как значение scope.something был обновлен в родительском контроллере.

Другие вопросы по тегам