簡體   English   中英

如何在自定義指令中使用ngModel指令的格式化程序/解析器?

[英]How to use ngModel directive's formatter/parsers in a custom directive?

我想在指令中使用ng-model格式器/解析器。 問題是格式化程序無法正常工作,它可以正確返回結果,但未在輸入框中應用。 (請參閱演示中的控制台日志)。

如果我在沒有我的指令模板的情況下直接在輸入標簽上運行指令,則它會按預期工作。 我看不出有什么問題。 這可能是一個范圍界定的問題,但我不確定。 我怎樣才能解決這個問題?

該指令如何工作

該指令將HTML實體存儲在模型中(例如© ),並在文本輸入字段中顯示為版權符號(©)。 稍后,我將帶按鈕的符號添加到文本字段。 對我而言,這並不是一個真正的應用程序,僅用於學習Angular。

以下是我的代碼或jsfiddle中的演示。

 angular.module('demoApp', ['ngSanitize']) .controller('mainController', function($scope) { $scope.myModel = '&copy;&reg;'; }) .directive('myInput', function($timeout, $sanitize, $sce, $parse) { return { restrict: 'EA', require: 'ngModel', scope: { inputText: '=ngModel' }, template: '<div>some other html here... <input ng-model="inputText"/></div>', link: function(scope, element, attrs, ngModel) { /*scope.$watch('inputText', function() { scope.$eval(attrs.ngModel + ' = inputText'); }); scope.$watch(attrs.ngModel, function(val) { scope.inputText = val; });*/ /*scope.$watch('ngModel', function() { scope.inputText = scope.ngModel; });*/ console.log(element); /*ngModel.$render = function() { element.html('click me!! counter: ' + ngModel.$viewValue); };*/ //format text going to user (model to view) ngModel.$formatters.push(function(value) { var decoded = angular.element('<div/>').html($sce.trustAsHtml(value)).text(); console.log('formatter', value, decoded, $sce.trustAsHtml(value)); //, $parse(value)); return decoded;//$sce.getTrustedHtml(value); }); //format text from the user (view to model) ngModel.$parsers.push(function(value) { console.log('parser', value, $sanitize(value)); return $sanitize(value); ///\\d+/.exec(value)[0]); ///\\d+/.exec(value)[0]); }); } }; }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-sanitize.js"></script> <div ng-app="demoApp" ng-controller="mainController"> model value = {{myModel}}<br/> <my-input ng-model="myModel"/> </div> 

我找到了解決方法。 如注釋中提到的,使用另一個指令可以正常工作,因為ngModel可以直接在輸入元素上工作,我認為可以使用另一個指令來使其正常工作。 解析器(查看模型)現在也正在工作。

我仍然不確定為什么我以前的代碼會失敗。 但我可以找出以下幾點:

如果ng-model指令位於模板內部,則格式化程序將運行兩次。 首先使用正確格式的符號(©®),然后在第二次運行時,將視圖值設置為&copy;&reg; 並將其添加到輸入字段。 似乎在輸入標簽處調用指令的ngModel的解析器被調用並清理符號,但我不確定。

如果有人有想法如何在不使用其他指令的情況下進行修復,請告訴我。

因此,請查看下面或此jsfiddle中的工作代碼。

 angular.module('demoApp', ['ngSanitize']) .controller('mainController', function ($scope) { $scope.myModel = '&copy;&reg;'; }) .directive('encodeEntity', function ($sanitize, $sce) { return { restrict: 'A', require: 'ngModel', link: function (scope, element, attrs, ngModel) { /*ngModel.$render = function () { //console.log(ngModel.$viewValue); console.log('rendered'); element.val(ngModel.$viewValue); };*/ function decode(value) { return angular.element('<div/>') .html($sce.trustAsHtml(value || '')).text(); } //format text going to user (model to view) ngModel.$formatters.push(function (value) { var decoded = decode(value); console.log('formatter', value, decoded); return decoded; }); //format text from the user (view to model) ngModel.$parsers.push(function (value) { console.log('parser', value, $sanitize(value)); var newModelValue = $sanitize(value), inputStr = '' + value, startPos = inputStr.indexOf('&'), last = inputStr.length - 1; if ( startPos !== -1 && inputStr[last] == ';') { console.log('update symbol'); ngModel.$setViewValue(decode(newModelValue)); ngModel.$render(); } return newModelValue; }); } } }) .directive('myInput', function () { return { restrict: 'EA', require: 'ngModel', scope: { inputText: '=ngModel' }, //terminal: true, // terminal true deactivates any directives that are running at lower priority, eg an ng-model directive inside of the template template: '<div>Template:<input ng-model="inputText" encode-entity/></div>', link: function (scope, element, attrs, ngModel) { /* do stuff of main directiv here.... */ } }; }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-sanitize.js"></script> <div ng-app="demoApp" ng-controller="mainController">model value = {{myModel}} <br/> <my-input ng-model="myModel" /> </div> 

問題是angularjs將對您要顯示的所有內容進行編碼。 如果要顯示html,可以更改代碼,例如:

<div ng-app="demoApp" ng-controller="mainController">
    model value = <span ng-bind-html="myModel"></span><br/>
    <my-input ng-model="myModel"/>
</div>

ng-bind-html需要一個由以下對象返回的對象: $sce.trustAsHtml

因此,在格式化程序中,只需:

return $sce.getTrustedHtml(value);

(不確定為什么將其注釋掉)

暫無
暫無

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

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