簡體   English   中英

是否可以在沒有深層$ watch的情況下檢測指令中ng-model的更改

[英]Is it possible to detect changes to ng-model in a directive without a deep $watch

我正在編寫帶有自定義驗證邏輯的指令來驗證對象。

HTML:

<input type="hidden" name="obj" ng-model="vm.obj" validate-object />

JS:

angular
  .module('myApp')
  .directive('validateObject', function () {
    return {
      restrict: 'A',
      require: 'ngModel',
      link: function (scope, element, attrs, ngModelCtrl) {
        ngModelCtrl.$validators.validateObject = myValidator;

        function myValidator (modelValue, viewValue) {
          return validateObject(modelValue);
        }

        function validateObject (obj) {
          // Look inside the object
        }
      }
    }
  });

問題在於,當更改對象內部的屬性時,驗證程序不會運行。

我可以添加一個帶有objectEquality === true$watch ,然后使用驗證邏輯手動添加$setCustomValidity 像這樣:

link: function (scope, element, attrs, ngModelCtrl) {
  scope.$watch(attrs.ngModel, onModelChange, true);

  function onModelChange (newValue) {
    ngModelCtrl.$setCustomValidity('validateObject', validateObject(newValue))
  }

  function validateObject (obj) {
    // Look inside the object
  }
}

但是我不喜歡使用老式的手動使用$setValidity NgModelController方式,加上添加手動$watchNgModelController已經有在更新過程中注冊的方式(例如$formatters ),此外, $watch是一個很深的方法可能會有性能問題。

我搞錯了嗎? 有沒有更好的辦法?

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngModel.js#L699

if (ctrl.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !ctrl.$$hasNativeValidators)) {
  return;
}

ngModel對模型的較舊版本執行平面相等性檢查,因此對象內部的任何更改都不會反映在ngModel或ngChange上。

推薦的方法是使用不可變數據,這意味着每次更改模型(對象)時,都應創建一個新副本:

function changeModel(){
  this.vm.name = "roy";
  // Create a new object for ngModel;
  this.vm = angular.copy(this.vm);
}

編輯

我記得我以前解決過上一個問題。 您希望具有一組綁定到對象屬性的ng模型,並為整個對象設置1個更改偵聽器。

這是我的解決方案: http : //plnkr.co/edit/6tPMrB8n1agINMo252F2?p=preview

我要做的是創建一個新的指令“ formModel”,該指令必須放在表單元素上。 Angular有一個帶有控制器的form指令。 NgModelController需要一個父表單控制器,然后它將其自身添加到表單中(這是您在整個表單上獲得有效性的方式)。 因此,在我的指令中,我裝飾了表單的$ addControl方法,並為每個通過$ viewChangeListeners添加自身的ngModelController添加了一個偵聽器,現在在表單內ngModel的每次更改時,formModel指令都將復制整個對象並觸發$ setViewViewValue 。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM