gpt4 book ai didi

javascript - AngularJS - 如何处理圆形 watch ?

转载 作者:行者123 更新时间:2023-12-04 00:02:33 25 4
gpt4 key购买 nike

假设我正在使用一个指令,该指令通过双向绑定(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 回调? 显然,如果我选择一个新日期,流程将如下:
  • Watcher #2 被调用 - 它修改 selectedUnixTimestamp
  • 观察者 #1 被调用 - 它修改 selectedDate
  • 再次调用 Watcher #2(新对象引用) - 它修改 selectedUnixTimestamp

  • 但除了第一个电话,我不想要任何电话。我怎样才能实现它?

    显然,一种方法是执行以下操作:
    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) {

    但这仅适用于此特定示例,不能解决一般问题

    最佳答案

    如何使用圆形 watch ?我想答案是,尽量不要这样做。

    你可以试试这个,虽然我相信你的例子有更好的解决方案。

    仅使用一种 watch 功能:

    您可以使用函数作为 watch 的第一个参数。该函数将被调用,直到它返回的值稳定(与上次相同)。因此,您可以像这样创建 $watch:

    $scope.$watch(function() {
    return {
    timestamp: scope.selectedUnixTimestamp,
    date: scope.selectedDate
    }
    }, function(newVal, oldVal) {
    // Note that newVal and oldVal here is on the form of the object you return in the watch function, and hence have properties: timestamp and date.
    // You can compare newVal.date to oldVal.date (same with timestamp) to see which one has actually changed if you need to do that.
    }
    true); // You need a deep watch (the true param) to watch the properties on the object

    关于javascript - AngularJS - 如何处理圆形 watch ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21638300/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com