2014-11-05 88 views
1

我正在檢查別人的代碼,我發現他們的指令中有$scope.$apply指令是否應該調用scope.apply?

這種情況是我們從DOM獲得了一些事件,我們想要改變範圍。

根據我的經驗,指令應該調用apply。它會導致一些奇怪的副作用。

其中之一是在指令的測試。我所有的測試具有相同的圖案

$compile("<the html>")(scope); 
scope.$digest(); --> will error if directive calls apply 
  • 如果指令調用申請?
  • 當您從DOM中未包含角度的事件時,建議的解決方案適用於範圍變更?

回答

2

我會說調用$ scope。$ apply或$ scope。$ digest通常(雖然不總是)一個壞主意。
對於你的例子,註冊DOM事件可以通過使用ng-click,ng-keydown等角度來完成,這將隱藏調用$ apply或$ digest的需要。
它甚至需要的原因很明顯是因爲有一些代碼在角度外執行「外部」角度,這意味着角度生態系統之外,所以基本上角度不會「知道」事件(或任何其他數據相關事物)發生了。
所以總結一下,應該有一個很好的理由來調用$ apply或$ digest。
還有其他嗎?那麼,你可以在你自己的指令中封裝這些事件捕獲(雖然大多數如果不是全部都是角度覆蓋的話)。這些角度本身就是這樣做的,並且僅在事件本身實際需要時纔會導致$ apply或$ digest。

/編輯/
例如,角度的NG-點擊的簡化版本,可以翻譯成你自己的指令:

app.directive('myClick', ['$parse', function ($parse) { 
    return { 
     restrict: 'A', 
     link: function (scope, element, attrs) { 
      var clickHandler = $parse(attr.myClick); 
      element.on('click', function(event) { 
       // Do some of your own logic if needed. 
       scope.$apply(function() { 
        // Calling the event handler. 
        clickHandler(scope, {$event: event}); 
       }); 
      }); 
     } 
    } 
}]); 

通過封裝此事件處理程序,它可以重複使用(在此一個指令形式),並且因爲是角度世界的一部分,所以使用此指令的任何其他邏輯都不必擔心$ apply或$ digest。這也意味着它現在可以使用聲明(而不是操作上),這是什麼角度渴望。

有一點需要注意,這個指令沒有隔離的作用域,也沒有在作用域上引入任何其他的新變量(事件處理函數在鏈接函數中被解析)。這很重要,因爲這意味着對父範圍(需要「知道」這個事件的範圍 - 基本上是主範圍)沒有額外的副作用,因爲指令的範圍是繼承的。

P.S您還可以考慮overriding指令或decorating其他服務的角度。

+0

你能否詳細說明「封裝這些事件」? – 2014-11-05 15:24:33

+0

查看附件。 – Tomer 2014-11-06 06:57:56

+0

所以這是我沒有得到 - 如果我點擊一個按鈕,而我已經在一個摘要循環中會發生什麼? – 2014-11-07 07:47:05

0

那麼......如果你的指令包裝了一些本地事件或者angulr範圍以外的任何東西,你沒有比調用「$ apply()」更多的選項。根據我的經驗,如果在角度範圍內和從外部角度(例如ng-click以及window-click事件或其他)調用此函數,將只會導致錯誤。如果是這種情況,您仍然可以使用$ timeout-Service。這不是最好的解決方案,但是從我所聽到的甚至是來自角度團隊的建議之一。

相關問題