2013-07-25 83 views
1

我想訂閱ngChange事件,但是來自代碼而不是標記。也就是說,給定一個$ scope和一個可以通過ngModel綁定的表達式,我想通過綁定到該表達式的任何ngModel指令來訂閱對該表達式所做的任何更改。這可能嗎?

類似:

$scope.field = "hello"; 
$scope.onButtonClick = function() { 
    $scope.field = "button clicked!"; 
} 

// this callback is only when the user types in an input bound to field 
// not when they click the button with ng-click="onButtonClick()" 
$scope.$watchNgChange("field", function() { 
    console.log("user caused field to change via a binding"); 
}); 

// this callback is called for both ngModel binding changes and onButtonClick. 
$scope.$watch("field", function() { 
    console.log("field was changed"); 
}); 

我不能只用$手錶,因爲這將捕獲所有的變化,包括從數據庫加載數據,從納克單擊回調,並從開始變化$監視其他表達式的回調(在這種情況下,如果有任何循環引用,那麼很容易讓$ watch回調進入無限循環並在10個摘要循環後出錯),以及誰知道還有什麼。

回答

3

首先,隨時嘗試做這樣的事情是一個壞主意 - 我只是在解決我的代碼中的設計問題或我的業務邏輯中的邏輯問題。一般來說,代碼不應該關心數據如何改變,只是它已經改變了。

其次,$ watch可以給你新的和舊的價值 - 這對我來說已經足夠了。如果舊值不等於新值,我想更新相關數據模型。如果新老價值相同,我想忽略更新。

最後,您可能會考慮在您的路由中使用resolve來消除「數據庫加載」,因爲完全定位的數據可以傳遞到您的控制器(假設您返回承諾)。

+0

我的級聯更新依賴關係圖在其中有周期,而$ watch的非確定性特性使得無法在所有情況下都正確地遍歷圖,例如確保每個節點只針對情況A處理一次,但允許它在場景B中被處理兩次。另外,舊的!=新的檢查不足以終止無限的$摘要循環,除了最微不足道的用例外。如果取決於我,我只會使用ngChange並完成它,但這不取決於我,我正在尋找解決方法。 –

+0

將此標記爲答案 - 因爲我開始相信我的想法並不是一個好的開始。感謝您的解決方案建議。我會研究它。 –

1

不要這樣做,它聽起來像是在嘗試將DOM邏輯(例如,如果用戶已經與DOM元素交互)引入控制器。

如果您閱讀了ngChange指令的源代碼,您會發現它需要一個ngModel,它被用作視圖和控制器之間的橋樑。

我建議創建一個模型的副本,並使用該副本在您的視圖中使用ngModel + ngChange進行數據綁定,然後您可以$觀看該副本並執行任何您想要的操作。

$scope.field = "hello"; //the field you care 
$scope.fieldCopy = $scope.field; //use 'fieldCopy' for databinding 

在HTML代碼中你可以改變模型fieldCopy

<input ngModel="fieldCopy" name='foo' /> 
<input ngModel="fieldCopy" name='foo2' /> 

然後,您看fieldCopy用於與用戶交互的變化和變化複製到「場」的多種方式:

$scope.$watch("fieldCopy", function() { 
    $scope.field = $scope.fieldCopy; 
    console.log("user caused field to change via a binding"); 
}); 

如果你想保持fieldCopy同步與現場再添手錶:

$scope.$watch("field", function() { 
    $scope.fieldCopy = $scope.field; 
}); 
+0

嗯,關閉,但是如果$ scope.field從另一個回調中改變,那麼$ scope.fieldCopy不會同步。 –

+0

在這種情況下,您可以將手錶添加到現場並同步字段複製 – DavidLin

+0

只有存在有問題字段的可靠的angular.equals時纔可能。否則,將無法阻止無限的$摘要循環。 –

1

傑里米你只是描述了什麼Angular被稱爲指令。每次需要觸摸DOM時,始終使用指令是最佳做法。這個邏輯不應該存在於控制器甚至服務中。

指令是一個非常棘手的問題,但它有大量的文檔。

訪問docs.angularjs。組織/指令

相關問題