2014-10-31 189 views
6

用法:AngularJS覆蓋隔離指令範圍

<my-directive my-var="true"></my-directive> 

指令:

app.directive('myDirective', [ 
    function() { 
     var definition = { 
      restrict: "E", 
      replace: false, 
      transclude: false, 
      scope: { 
       myVar: '@', 
      }, 
      controller: ['$scope', function($scope) { 
       console.log($scope.myVar); // "true" 
       $scope.myVar = "false"; 
       console.log($scope.myVar); // "false" 

       setTimeout(function() { 
        console.log($scope.myVar); // "true" (!) 
       }, 100); 
      }] 
     }; 

     return definition; 
    } 
]); 

控制檯輸出

"true" 
"false" 
"true" 

究竟是什麼發生在這裏?該變量作爲字符串(「真」)傳遞,我正在改變它,然後它被替換了嗎?我想了解這裏的週期。這是因爲有一些額外的編譯或摘要循環踢入並重新計算所有隔離的範圍值?我認爲一旦設置,像這樣傳遞的變量(@,只是在指令中的字符串)會保持不變?

有沒有什麼辦法可以在指令內連接一段時間,在這之後字符串變量不會被替換,或者它會總是像這樣對每個摘要或什麼都起作用,而且我不得不使用$ watch?

+0

這與相似的問題有關 - http://stackoverflow.com/questions/22967024/initializing-isolated-scope-in​​side-a-directive,但我沒有找到原來的答案是完整的,因爲我使用eval重新評估這些字符串爲布爾值,並不是真的想改變它們的值,而是讓它們保持布爾值。所以我將其中一個轉換爲布爾值,然後將它重寫爲字符串。 – rattkin 2014-10-31 16:29:59

回答

7

@將父範圍綁定到隔離的範圍,它是單向(而非一次性)綁定。所以,外部範圍的任何更改都會重置指令隔離範圍中的值。

Under the covers,對元素屬性使用「@」角度調用attrs.$observe。這樣做的目的是在編譯後的下一個$ digest循環中排隊觀察者函數。該觀察者函數是每當指定給屬性的內插值發生更改時設置範圍變量的內容。

因此,高層次的步驟是:

1) for `@` scope variable, set an observer function and queue it for later 
2) set `@` scope variable to the interpolated value 
3) run the controller, pre- and post-link functions 
... 
N) observer runs against interpolated value and sets the scope value 

因此,考慮到這一點,你可以看到現在爲什麼你的變化不存在。如果在所有這些步驟之後 - 即超時或響應某個事件,那麼它就會生效。如果屬性插值沒有改變,則只有

這不是「=」。

下面是一個plunker說明差異。

如果你想要的變量一次性通道,只是用在鏈接功能或屬性控制器

scope.myVar = $attrs["my-var"]; 

設置範圍變量,然後從範圍中刪除myVar

+0

你還在找什麼?它回答你的問題。它爲什麼改變? - 因爲它是單向綁定,即父範圍變量的任何更改都會導致綁定的隔離範圍變量發生更改。在你的問題中,你做了一個不正確的假設。 – 2014-11-07 15:30:59

+0

我知道有約束力建立。我不知道(並且想知道)什麼會觸發摘要週期重新評估,以便它再次填充新的對象,即使它之前已經做了,而且它的值也沒有改變。這些都是很深的內在東西。 – rattkin 2014-11-07 15:35:42

+0

$ digest cycle在任何組件調用'$ scope。$ apply'時啓動。它在第一次運行時也會下降。如果你知道綁定,那麼你知道它使用髒檢查完成 - 因爲你改變了運行之間的值,所以重新應用了綁定。看到我自己的問題和[回答](http://stackoverflow.com/a/25908745/968155) – 2014-11-07 16:00:22