假设我正在使用一个指令,该指令通过双向绑定(bind)以 unix 时间戳的形式给出日期,但还提供了一个日历小部件来更改选择。
日历小部件与日期对象一起使用,我无法更改输入数据格式,并且我不想修改日历以支持 unix 时间戳。这也只是一个例子,问题是关于与循环观察者一起工作的一般方式。
范围看起来像这样:
scope.selectedUnixTimestamp; // this comes from the outside
scope.selectedDate;
scope.$watch('selectedUnixTimestamp', function(newV, oldV) {
$scope.selectedDate = new Date(newV*1000);
});
scope.$watch('selectedDate', function(newV, oldV) {
$scope.selectedUnixTimestamp = Math.floor(newV.getTime()/1000 + 0.000001);
});
我的问题是: 我该怎么做才能避免额外调用 $watch 回调? 显然,如果我选择一个新日期,流程将如下:
但除了第一个之外,我不想要任何这些电话。我怎样才能实现它?
显然,一种方法是执行以下操作:
scope.selectedUnixTimestamp;
scope.selectedDate;
var surpressWatch1 = false;
var surpressWatch2 = false;
scope.$watch('selectedUnixTimestamp', function(newV, oldV) {
if(surpressWatch1) { surpressWatch1 = false; return; }
$scope.selectedDate = new Date(newV*1000);
surpressWatch2 = true;
});
scope.$watch('selectedDate', function(newV, oldV) {
if(surpressWatch2) { surpressWatch2 = false; return; }
$scope.selectedUnixTimestamp = Math.floor(newV.getTime()/1000 + 0.000001);
surpressWatch1 = true;
});
但是维护这样的代码很快就变成了 hell 。
另一种方法是执行以下操作:
scope.selectedUnixTimestamp;
scope.selectedDate;
scope.$watch('selectedUnixTimestamp', function(newV, oldV) {
if(newV*1000 === scope.selectedDate.getTime()) { return; }
$scope.selectedDate = new Date(newV*1000);
});
scope.$watch('selectedDate', function(newV, oldV) {
if(scope.selectedUnixTimestamp*1000 === newV.getTime()) { return; }
$scope.selectedUnixTimestamp = Math.floor(newV.getTime()/1000 + 0.000001);
});
但是如果数据转换比
* 1000
更复杂,它可能会非常昂贵另一种方法是观察原始值而不是日期对象:
scope.$watch('selectedDate.getTime()', function(newV, oldV) {
但这仅适用于此特定示例,并不能解决一般问题
最佳答案
Angular 框架建立在以下假设之上:
例如,准备好与 REST 服务同步的某物的真实可信值(value)在模型中只存在一次。
记住这一点,你永远不会写循环观察者。
如果您有两种不同的方法来改变模型值,您将编写需要 ngModelController 实例并提供正确的格式化程序和解析器功能的指令。
关于javascript - AngularJS - 如何处理圆形 watch ?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21638300/