2014-01-06 86 views
10

我有一個Angular.js應用程序,可以在複雜的對象模型中執行大量的會計類型計算(收入,成本,利潤等)。對對象模型任何部分的更改都需要重新執行所有計算。此外,對象模型的許多更改可以使用綁定直接從我的模板中進行 - 不需要控制器進行中間調整。如何知道Angular.js摘要循環何時開始(或結束)?

許多計算結果都需要同時顯示給用戶有助於下游計算。例如,收入顯示給用戶,但也用於計算利潤(也顯示給用戶)。但是,在每個消化循環中兩次計算收入毫無意義(這是一個複雜的計算),因此明顯的優化是在首次計算時記憶,然後在循環的持續時間內重用此記憶值。

問題是我需要在摘要週期的開始或結束時清除這些記憶。一種方法是讓控制器在進行計算之前攔截每一個可能的變化來源並手動清除對象模型。相反,我更願意繼續使用已經建立的綁定。

據我所知,我需要的是一種方法來知道摘要週期何時開始或何時完成。當我收到這個通知時,我可以重置記憶。

Angular $watch documentation說:

如果您希望收到通知,只要$消化被調用,您可以 註冊不聽者watchExpression功能。 (由於 watchExpression可以執行多次,每次$檢測到 變化時消化週期,對多次調用你的聽衆準備。)

這是對我沒有用,因爲結算上的每次迭代memoizations消化週期會挫敗讓他們擺在首位的目的。我只需要一個通知每個摘要週期。

我該怎麼做,或者是否有解決問題的替代方法?

+0

_「...我需要清除這些記憶...」 - - 爲什麼? – Stewie

+0

'是否有解決問題的替代方法?......真的不清楚實際問題是什麼 – charlietfl

+0

如果您創建服務來計算此成本等並手動調用計算方法會怎樣? –

回答

9

好吧,我想我終於明白了一些事情,所以想我會回答我自己的問題。

有一種稱爲$$postDigest的私人Angular方法,它將在下一個摘要循環結束後回調函數。然而,它只運行一次,如果你試圖讓它重新計劃自己遞歸,它會進入一個無限循環。

要變通解決此問題,您可以改爲使用$$postDigest結合常規$watch。如果你有一個叫做你想一個控制器來調用後,每消化週期fn功能,你會添加一些像這樣的控制器功能:

... 
var hasRegistered = false; 
$scope.$watch(function() { 
    if (hasRegistered) return; 
    hasRegistered = true 
    // Note that we're using a private Angular method here (for now) 
    $scope.$$postDigest(function() { 
    hasRegistered = false; 
    fn(); 
    }); 
}); 
... 

這是基於a code fragment by Karl Seamon。顯然,在$scope上調用私有方法並不理想。希望沿着這些方向的$postDigestWatch方法最終可以添加到Angular中。

對於我原來的問題,你爲什麼想要做這樣的事情,在評論中出現了一些混淆:如果你還不清楚,請查看this blog post I wrote,其中涵蓋了我的特定用例。

相關問題