1

我有一個問題,其中隔離作用域的指令沒有通過綁定到它的parent.parent作用域進行更改。總之,我認爲對指令的隔離範圍中的一個屬性所做的更改綁定到一個父屬性會一直向上傳播該屬性的父範圍(該屬性是從父屬性範圍繼承而來的)開始),但它不。它僅更改直接父級作用域上的值,而parent.parent作用域具有舊值。更糟糕的是,對parent.parent範圍屬性的任何更改都不再逐漸下移到隔離範圍或其直接父級。我知道這是Javascript的原型繼承的正常行爲,Angular作用域是建立在它的基礎上的,但在這種雙向數據綁定的情況下並不希望這樣做,我正在尋找Angular的解決方案。與parent.parent作用域的雙向綁定

這裏是行爲的一個例子:http://jsfiddle.net/abeall/RmDuw/344/

我的HTML包含一個控制器DIV(MyController1),它是另一個控制器DIV(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在外MyController範圍定義myMessage,內MyController2範圍繼承和結合myMessagemessage的指令,並且MyDirectivemessage定義爲隔離範圍屬性。在每個級別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的變化按鈕幾次,所有級別都會更新(向下繼承)。

  • 如果您然後單擊MyDirective的更改按鈕,它會更新MyController2(綁定向上),但不會以任何方式更改MyController1

  • 在此之後,單擊MyController1的更改按鈕不再涓涓細流至MyController2MyDirective範圍,反之亦然。兩人現在彼此分開。這就是問題。

所以我的問題是:

  • 角是否有辦法允許綁定或(在這種情況下myMessage)範圍屬性的繼承淌一路上漲父範圍?

  • 如果沒有,用什麼方式,我應該同步的指令的分離範圍爲parent.parent控制器範圍的屬性變化?該指令無法瞭解其父母的結構。

+0

這似乎是JavaScript的原型繼承的副作用。發生這種情況是因爲您使用的是基元而不是對象,並且JavaScript繼承允許在原型鏈中隱藏基元。我不能解釋它幾乎以及[這個答案],(http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs),我建議徹底閱讀。 – Claies

+0

是的,謝謝,我明白這是問題,但有沒有使用Angular綁定的解決方案?如果沒有,那麼還有哪些其他的Angular解決方案? – Aaron

+0

使用一個對象,或使用ControllerAs語法,其中控制器是對象。由於許多其他原因,我強烈建議使用ControllerAs語法,但主要是因爲它打破了對$ scope的依賴性,有助於繼承問題,並且更接近於angular 2語法。 – Claies

回答

1

as @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/