簡體   English   中英

從$ watch觸發ngModelController $解析器管道

[英]Trigger ngModelController $parsers pipeline from a $watch

我正在編寫一個需要ngModel的指令,並添加格式化程序和解析器來操作該值。 它工作得很好,但由於操作依賴於外部數據,我必須觀看,我正在尋找一種方法來更新這款手表的模型值。 我試圖調用$setViewValue但沒有任何反應(因為$ viewValue沒有改變??)。

在下面的簡單示例中,對“factor”的更改不會更新模型值:

 angular.module('app', []).directive('multiply', multiplyDirective); function multiplyDirective() { return { restrict: 'A', require: 'ngModel', scope: { factor: '=multiply' }, link: function(scope, elem, attr, ngModel) { ngModel.$formatters.push(function (value) { return value / scope.factor; }); ngModel.$parsers.push(function (value) { return value * scope.factor; }); scope.$watch('factor', function () { // how to run the parsers pipeline to update modelvalue? ngModel.$setViewValue(ngModel.$viewValue); }); } } } 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.min.js"></script> <body ng-app ng-init="factor = 1; value = 1"> <input type="number" ng-model="value" multiply="factor" /> x <input type="number" ng-model="factor" /> = {{ value }} </body> 

編輯:如果我調用內部$$parseAndValidate方法,它可以工作,但我想知道是否有一個公共API來強制執行更新。

編輯:我想通了,那個ngModel.$setViewValue(ngModel.$viewValue);的行為ngModel.$setViewValue(ngModel.$viewValue); 1.3.0更改。 使用1.2.x代碼有效!

有點晚了,但我已經描述了你如何在這里做到這一點 這適用於AngularJS 1.6.x.

基本上你可以使用$setViewValue()觸發$parsers pipeline

下面是一個代碼片段,允許您通過“劫持”$ parsers管道以編程方式將ngModel設置為您喜歡的任何內容。 這是使用閉包完成的。

使用這樣的閉包設置$解析器:

const hijack = {trigger: false; model: null};
modelCtrl.$parsers.push( val => {
   if (hijack.trigger){
        hijack.trigger = false;
        return hijack.model;
   }
   else { 
      // .. do something else ...
   })

然后,為了(重新)設置模型,您需要通過使用modelCtrl.$setViewValue('newViewValue')更改$viewValue來觸發管道modelCtrl.$setViewValue('newViewValue') (是的,新視圖值必須與當前值不同)。

const $setModelValue = function(model){
    // trigger the hijack and pass along your new model
    hijack.trigger = true;
    hijack.model = model; 
    // assuming you have some logic in getViewValue to output a viewValue string
    modelCtrl.$setViewValue( "some new view value" ); 
    }

您的指令根本沒有加載。 您需要將模塊名稱提供給ng-app,例如<body ng-app="app"> 然后,只要修改因子,就調用ngModel.$setViewValue(ngModel.$viewValue)

 angular.module('app', []).directive('multiply', multiplyDirective); function multiplyDirective() { return { restrict: 'A', require: 'ngModel', scope: { factor: '=multiply' }, link: function(scope, elem, attr, ngModel) { ngModel.$formatters.push(function (value) { return value / scope.factor; }); ngModel.$parsers.push(function (value) { return value * scope.factor }); scope.$watch('factor', function () { // how to run the parsers pipeline to update modelvalue? ngModel.$setViewValue(ngModel.$viewValue); }); } } } 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <body ng-app="app" ng-init="factor = 1; value = 1"> <input type="number" ng-model="value" multiply="factor" /> x <input type="number" ng-model="factor" /> = {{ value }} </body> 

從v1.3.18的來源,我看不到公開的api。 管道來自$$ parseAndValidate方法,該方法也是從$ commitViewValue調用的 (需要提交/設置不同的值,否則它將返回

暫無
暫無

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

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