$parsers 和 $formatters 只被调用一次,而不是在每次值更新时调用
$parsers and $formatters are being called only once, instead of on every value update
我正在尝试创建一个名为 currency
的指令,它在输入的文本之前附加一个 $
。美元符号应始终显示且不可删除。
这是我的代码:
app.directive('currency', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elem, attrs, controller) {
// view -> model
controller.$parsers.push(function (viewValue) {
viewValue = viewValue.replace(/^$/, '');
controller.$viewValue = viewValue;
return viewValue;
});
// model -> view
controller.$formatters.push(function (modelValue) {
modelValue = '$' + modelValue;
controller.$modelValue = modelValue;
return modelValue;
});
}
};
});
工作示例:https://jsfiddle.net/U3pVM/29012/
如您所见,美元符号最初是附加的,但可以删除并且之后不会附加。我推送到 $formatters
的函数似乎只被调用了一次。它应该像那样工作还是我错过了什么?我怎样才能实现所需的行为?
好的,我已经尝试了一种解决方法,它有效,但我不确定这是否是正确的方法。
已更新 fiddle:https://jsfiddle.net/U3pVM/29014/
controller.$parsers.push(function (viewValue) {
//console.log(viewValue.substring(0,1));
if(viewValue.substring(0,1) != "$"){
var view_value = "$" + viewValue;
controller.$setViewValue(view_value);
controller.$render();
}
viewValue = viewValue.replace(/^$/, '');
//controller.$viewValue = viewValue;
console.log(viewValue);
return viewValue;
});
P.S:我不确定您为什么要在 link
函数中将 ngModel
作为 controller
注入。这可能是一个错误。
我认为您不太了解 $parsers 和 $formatters 的作用。每当您在输入字段中输入内容时,$parsers 都会负责将此值转换为模型值。格式化程序负责将模型值转换为输入字段中的显示值。
您试图做的是在有人向字段中输入内容时更改输入字段的内容($formatter 功能)($parser 功能)。
虽然我确信有一些解决方法可以让它以这种方式工作,但您在这样做时误用了 $parsers 和 $formatters 的概念。相反,您应该查看一个自定义指令(或扩展您拥有的指令)以添加到执行您正在尝试执行的操作的输入中,例如通过传递 keyups。
编辑
请参阅以下 link 函数的代码示例,让您了解我的意思:
link: function (scope, elem, attrs, controller) {
elem.bind('keyup', function(evt) {
// Change the displayed value after every keypress
// This function is an example and needs serious work...
// Perhaps you should even put this in a separate directive
var value = elem.val().replace(/[^[=10=]-9]/g, '');
if (value && value.substring(0,1) !== '$') {
value = '$' + value;
}
elem.val(value);
});
// view -> model
controller.$parsers.push(function (viewValue) {
// Any time the view changes, remove the $ sign and interpret the rest as number for the model
var modelValue = viewValue.replace(/^$/, '');
return parseFloat(modelValue);
});
// model -> view
controller.$formatters.push(function (modelValue) {
// Any time the model (number) changes, append it with a $ sign for the view
var viewValue = '$' + modelValue;
return viewValue;
});
}
或检查整个fiddle:https://jsfiddle.net/cL0hpvp4/
我正在尝试创建一个名为 currency
的指令,它在输入的文本之前附加一个 $
。美元符号应始终显示且不可删除。
这是我的代码:
app.directive('currency', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elem, attrs, controller) {
// view -> model
controller.$parsers.push(function (viewValue) {
viewValue = viewValue.replace(/^$/, '');
controller.$viewValue = viewValue;
return viewValue;
});
// model -> view
controller.$formatters.push(function (modelValue) {
modelValue = '$' + modelValue;
controller.$modelValue = modelValue;
return modelValue;
});
}
};
});
工作示例:https://jsfiddle.net/U3pVM/29012/
如您所见,美元符号最初是附加的,但可以删除并且之后不会附加。我推送到 $formatters
的函数似乎只被调用了一次。它应该像那样工作还是我错过了什么?我怎样才能实现所需的行为?
好的,我已经尝试了一种解决方法,它有效,但我不确定这是否是正确的方法。
已更新 fiddle:https://jsfiddle.net/U3pVM/29014/
controller.$parsers.push(function (viewValue) {
//console.log(viewValue.substring(0,1));
if(viewValue.substring(0,1) != "$"){
var view_value = "$" + viewValue;
controller.$setViewValue(view_value);
controller.$render();
}
viewValue = viewValue.replace(/^$/, '');
//controller.$viewValue = viewValue;
console.log(viewValue);
return viewValue;
});
P.S:我不确定您为什么要在 link
函数中将 ngModel
作为 controller
注入。这可能是一个错误。
我认为您不太了解 $parsers 和 $formatters 的作用。每当您在输入字段中输入内容时,$parsers 都会负责将此值转换为模型值。格式化程序负责将模型值转换为输入字段中的显示值。
您试图做的是在有人向字段中输入内容时更改输入字段的内容($formatter 功能)($parser 功能)。
虽然我确信有一些解决方法可以让它以这种方式工作,但您在这样做时误用了 $parsers 和 $formatters 的概念。相反,您应该查看一个自定义指令(或扩展您拥有的指令)以添加到执行您正在尝试执行的操作的输入中,例如通过传递 keyups。
编辑
请参阅以下 link 函数的代码示例,让您了解我的意思:
link: function (scope, elem, attrs, controller) {
elem.bind('keyup', function(evt) {
// Change the displayed value after every keypress
// This function is an example and needs serious work...
// Perhaps you should even put this in a separate directive
var value = elem.val().replace(/[^[=10=]-9]/g, '');
if (value && value.substring(0,1) !== '$') {
value = '$' + value;
}
elem.val(value);
});
// view -> model
controller.$parsers.push(function (viewValue) {
// Any time the view changes, remove the $ sign and interpret the rest as number for the model
var modelValue = viewValue.replace(/^$/, '');
return parseFloat(modelValue);
});
// model -> view
controller.$formatters.push(function (modelValue) {
// Any time the model (number) changes, append it with a $ sign for the view
var viewValue = '$' + modelValue;
return viewValue;
});
}
或检查整个fiddle:https://jsfiddle.net/cL0hpvp4/