1

У меня проблема, когда директива с областью выделения не вносит изменений через привязку к своей области parent.parent.Двунаправленное связывание с областью parent.parent

Таким образом, я ожидал бы, что изменения, внесенные в свойство в области выделения, которые связаны с родительским свойством, будут распространять все пути родительских областей для этого свойства (свойство было унаследовано от области parent.parent для начала), но это не так. Он изменяет значение только в непосредственной родительской области, а область parent.parent имеет старое значение. Хуже того, любые изменения свойства scope parent.parent больше не текут до области выделения или ее непосредственного родителя. Я понимаю, что это нормальное поведение наследования прототипов Javascript, на котором построены угловые области, но в этом случае не требуется двусторонняя привязка данных, и я ищу решение в Angular.

Вот пример поведения: http://jsfiddle.net/abeall/RmDuw/344/

Мой HTML содержит контроллер DIV (MyController1), в нем есть другой контроллер ДИВ (MyController2), а в том, что директива (MyDirective):

<div ng-controller="MyController"> 
    <p>MyController1: {{myMessage}} <button ng-click="change()">change</button></p> 
    <div ng-controller="MyController2"> 
     <p>MyController2: {{myMessage}} <button ng-click="change()">change</button></p> 
     <p>MyDirective: <my-directive message="myMessage"/></p> 
    </div> 
</div> 

Код JavaScript определяет myMessage на внешних MyController сферу, внутренний MyController2 сфера наследует и связывает myMessage с message на директиве, и MyDirective определяет message как свойство области изоляции. На каждом уровне change() функция определяется которая изменяет локальное свойство сообщения:

var app = angular.module('myApp', []); 

function MyController($scope) { 
    var count = 0; 
    $scope.myMessage = "from controller"; 
    $scope.change = function(){ 
     $scope.myMessage = "from controller one " + (++count); 
    } 
} 

function MyController2($scope) { 
    var count = 0; 
    $scope.change = function(){ 
     $scope.myMessage = "from controller two " + (++count); 
    } 
} 

app.directive('myDirective', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     template: '<span>Hello {{message}} <button ng-click="change()">change</button></span>', 
     scope: { 
      message: "=" 
     }, 
     link: function(scope, elm, attrs) { 
      var count = 0; 
      scope.change = function(){ 
       scope.message = "from directive " + (++count); 
      } 
     } 
    }; 
}); 

Что вы заметите, что:

  • Если нажать кнопку Изменить MyController1 «s несколько раз, все уровни обновляются (он наследует вниз).

  • Если затем нажмите кнопку изменить MyDirective «s, он обновляет MyController2 (связывание вверх), но не меняет MyController1 каким-либо образом. не

  • После этой точки, нажав MyController1 «s Кнопка изменения больше не сочится вниз MyController2 и MyDirective объема, и наоборот. Теперь они отделены друг от друга. Это проблема.

Так что мой вопрос:

  • ли Угловая есть способ разрешить связывание или наследование свойств Scope (myMessage в данном случае) сочиться весь путь до родительских областей?

  • Если нет, то каким образом я должен синхронизировать изменения в области выделения директивы с свойствами области управления parent.parent? Директива не может знать о структуре своих родителей.

+0

Это, как представляется, является побочным эффектом JavaScript Prototype наследования. Это происходит потому, что вы используете примитивы, а не объекты, а JavaScript Inheritance позволяет спрятать примитивы в Prototype Chain. Я не могу объяснить это почти так же, как [этот ответ] (http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs), Я рекомендую внимательно прочитать. – Claies

+0

Да, спасибо, я понимаю, что это проблема, но есть ли решение, использующее Angular binding? Если нет, то какие еще существуют Угловые решения этой проблемы? – Aaron

+0

использовать объект или использовать синтаксис ControllerAs, где контроллер является объектом. Я настоятельно рекомендую синтаксис ControllerAs по многим другим причинам, но главным образом потому, что он нарушает зависимость от '$ scope', помогает с проблемами наследования и намного ближе к синтаксису углового 2. – Claies

ответ

1

как @Claies упоминается, используя controller as - отличная идея. Таким образом, вы можете прямо указать, какую область действия вы хотите обновить, а также легко сможете передавать области в методах.

Here is a fiddle of the results you were likely expecting

Синтаксис: ng-controller="MyController as ctrl1"

Тогда внутри: {{ctrl1.myMessage}} или ng-click="ctrl1.change()" и click="ctrl2.change(ctrl1)"

Это изменяет способ, которым Вы пишете свой контроллер, оставляя вне $scope зависимости, если вам это нужно по другим причинам, то держа модель.

function MyController() { 
    var count = 0 
    this.myMessage = "from controller" 
    this.change = function() { 
    this.myMessage = "from controller one " + (++count) 
    } 
} 

function MyController2() { 
    var count = 0 
    this.change = function (ctrl) { 
    ctrl.myMessage = "from controller two " + (++count) 
    } 
} 
+1

Определенно продается на синтаксисе «контроллер как», это выглядит намного лучше, чем наследование магического масштаба, на которое я полагался. Я закончил работу над этим, привязавшись к '$ parent.myMessage', но это, безусловно, более полное решение, и с чего я начну в будущем. – Aaron

0

Самое простое изменение заключается в использовании $ scope.msg.mymessage вместо $ scope.msg в вашем корневом контроллере.

function MyController($scope) { 
    var count = 0; 
    $scope.msg = {}; 
    $scope.msg.myMessage = "from controller"; 
    $scope.change = function(){ 
     $scope.msg.myMessage = "from controller one " + (++count); 
    } 
} 

Здесь представлена ​​раздвоенная скрипка (что звучит смешно) с предполагаемыми результатами.

http://jsfiddle.net/nk5cdrmx/

Смежные вопросы