我想在我的指令中使用 ng-model
格式化程序/解析器。问题是格式化程序未按预期工作,它正确返回结果,但未应用于输入框中。 (请参阅演示中的控制台日志)。
如果我直接在输入标记上运行指令而不使用指令模板,它将按预期工作。我看不出有什么问题。 这可能是一个范围问题,但我不确定。我该如何解决这个问题?
该指令如何工作
该指令在模型中存储 HTML 实体(例如 ©
),并在文本输入字段中显示为版权符号 (©)。稍后,我会将带有按钮的符号添加到文本字段。对于我来说,这并不是一个真正的仅用于学习 Angular 的应用程序。
下面是我的代码的演示或在这个jsfiddle中.
angular.module('demoApp', ['ngSanitize'])
.controller('mainController', function($scope) {
$scope.myModel = '©®';
})
.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 可以直接在输入元素上工作,我认为可以使用另一个指令来使其工作。此外,解析器( View 到模型)现在正在工作。
我仍然不确定为什么我之前的代码失败了。但我可以弄清楚以下几点:
如果 ng-model 指令位于模板内部,则格式化程序将运行两次。首先使用格式正确的符号 (©®),然后在第二次运行时将 View 值设置为 ©®
。并将其添加到输入字段中。
似乎输入标记处的指令的 ngModel
解析器被调用并清理符号,但我不确定。
如果有人知道如何在没有其他指令的情况下修复它,请告诉我。
所以看看下面或这个 jsfiddle 中的工作代码.
angular.module('demoApp', ['ngSanitize'])
.controller('mainController', function ($scope) {
$scope.myModel = '©®';
})
.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, e.g. 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>
关于javascript - 如何在自定义指令中使用 ngModel 指令的格式化程序/解析器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32150392/