AngularJS范围监视未触发

AngularJS scope watch is not triggering

本文关键字:监视 范围 AngularJS      更新时间:2023-09-26

我的作用域中有一个日期筛选字符串。

$scope.myModel = {date:""};

我还有一个jQuery日期选择器

<input date-value="myModel.date" date-picker />

在指令中更新此字符串(使用AngularJS-属性指令输入值更改)

.directive('datePicker', function ($timeout) {
  return {
    scope: {
      dateValue: "=?",
    },
    link : function (scope, elem, attrs) {
      $timeout(function() {
        elem.data('date-value', scope.dateValue);
        elem.bind('change paste', function (blurEvent) {
          if (elem.data('date-value') != elem.val()) {
            console.log('value changed, old value is:' + elem.data('date-value') +'new value is: ' + elem.val());
            elem.data('date-value', elem.val());
            scope.dateValue = elem.val();
          }
        });
      });
    },
  };
});

根作用域日期正在正确更新,我可以成功地将其发送到服务器,但我想在日期更改时做点什么。我的函数在页面初始化时被调用一次,然后再也不会调用了。

$scope.$watch("myModel.date", function(newVal, oldVal) {
  console.log("newVal: " + newVal + '  oldVal:' + oldVal);
  if (newVal == oldVal) {
    return;
  }
  // do something 
});

我在这里做错了什么?

我在其他一些堆栈溢出文章中读到,你可以通过scope.apply()强制检查你的作用域,但我的摘要中的作用域与我的控制器中的不同。所以这是有效的,但我对角度和摘要的了解还不够,无法解释原因。

elem.bind('change paste', function (blurEvent) {
          if (elem.data('date-value') != elem.val()) {
            console.log('value changed, old value is:' + elem.data('date-value') +'new value is: ' + elem.val());
            elem.data('date-value', elem.val());
            scope.dateValue = elem.val();
            if (!scope.$$phase) {scope.$apply();}
          }
        });

无论如何,这似乎太复杂了,当我在完成选择之前点击框时,元素绑定正在触发。最后,我在jQuerydatePicker参数的onClose上设置了一个函数调用。

datePickerParams = {
    controlType     : "select",
    timeFormat      : "hh:mm TT",
    onClose         : function(dateText, inst) {
                          $scope.myModel.dateText = dateText;
                          // do stuff
                      }
};

然后将其传递给指令。

.directive('datePicker', function ($timeout) {
  return {
    scope: {
      datetimePickerParams: "=",
    },
    link : function (scope, elem, attrs) {
      $timeout(function() {
        elem.datetimepicker(scope.datetimePickerParams)
      });
    },
  };
});

(也许是时候检查一下角度日期选择器,远离jquery日期选择器了。)

您是否尝试过使用true作为第三个参数来调用$watch?

$scope.$watch("myModel.date", function(newVal, oldVal) {
  console.log("newVal: " + newVal + '  oldVal:' + oldVal);
  if (newVal == oldVal) {
    return;
  }
  // do something 
}, true);

这将检查值相等性,而不是引用相等性。

查看此处$watch的文档,了解第三个参数[objectEquality]的作用。基本上将其设置为true会导致=>"使用angular.equals比较对象相等性,而不是比较参考相等性。"

此外,观察布尔标志可能比观察对象更好。在"myModel.date"更改时切换布尔标志,然后观察该标志。这将减少性能开销——检查对象比检查布尔标志要昂贵。

希望这能有所帮助!