如何更新 Angular 指令中的模型和视图值?
How to update both model and view value in Angular directive?
提前致歉,指令不是我的强项!
我有一个简单的仅属性指令,其目的是在 blur
字段时自动将字段中的字符串转换为 HH:mm 格式。这是指令:
(function () {
'use strict';
angular
.module('app.format-as-time')
.directive('formatAsTime', timeDirective);
timeDirective.$inject = [
'isValid'
];
function timeDirective (isValid) {
return {
require: 'ngModel',
restrict: 'A',
link: LinkFunction
};
function LinkFunction (scope, elem, attrs, ngModel) {
elem.bind('blur', function () {
var currentVal = ngModel.$modelValue,
formattedVal = '';
// Format something like 0115 to 01:15
if (currentVal.length === 4) {
formattedVal = currentVal.substr(0, 2) + ':' + currentVal.substr(2, 2);
// Format something like 115 to 01:15
} else if (currentVal.length === 3) {
formattedVal = '0' + currentVal.substr(0, 1) + ':' + currentVal.substr(1, 2);
// Format something like 15 to 00:15
} else if (currentVal.length === 2) {
formattedVal = '00:' + currentVal;
}
// If our formatted time is valid, apply it!
if (isValid.time(formattedVal)) {
scope.$applyAsync(function () {
ngModel.$viewValue = formattedVal;
ngModel.$render();
});
}
});
}
}
}());
以及关联的视图:
<div ng-controller="TestController as test">
<input type="text"
maxlength="5"
placeholder="HH:mm"
ng-model="test.startTime"
format-as-time>
<button ng-click="test.getStartTime()">Get Start Time</button>
</div>
以及关联的控制器:
(function () {
'use strict';
angular
.module('app.testModule')
.controller('TestController', TestController);
function TestController () {
var vm = this;
vm.startTime = '';
vm.getStartTime = function () {
console.log(vm.startTime);
}
}
}());
目前,该指令在视图中按预期工作,但我的控制器中的模型未更新,即输入将包含 01:15 但模型将 console.log()
115.
我试过使用:
scope: {
ngModel: '='
}
在指令中,但这并没有做任何事情。
我这样做的方式是否正确?如果是,我需要添加什么以确保模型和视图保持同步?
如果我做错了,正确的最好方法是什么?
问题在于这一行 ngModel.$viewValue = formattedVal;
Angular 有一个用于设置模型值的管道,其中包括 运行 通过注册的 $parsers 和 $validators 对其进行设置。设置值的正确方法是调用 $setViewValue(formattedVal)
,这将 运行 通过此管道的值。
提前致歉,指令不是我的强项!
我有一个简单的仅属性指令,其目的是在 blur
字段时自动将字段中的字符串转换为 HH:mm 格式。这是指令:
(function () {
'use strict';
angular
.module('app.format-as-time')
.directive('formatAsTime', timeDirective);
timeDirective.$inject = [
'isValid'
];
function timeDirective (isValid) {
return {
require: 'ngModel',
restrict: 'A',
link: LinkFunction
};
function LinkFunction (scope, elem, attrs, ngModel) {
elem.bind('blur', function () {
var currentVal = ngModel.$modelValue,
formattedVal = '';
// Format something like 0115 to 01:15
if (currentVal.length === 4) {
formattedVal = currentVal.substr(0, 2) + ':' + currentVal.substr(2, 2);
// Format something like 115 to 01:15
} else if (currentVal.length === 3) {
formattedVal = '0' + currentVal.substr(0, 1) + ':' + currentVal.substr(1, 2);
// Format something like 15 to 00:15
} else if (currentVal.length === 2) {
formattedVal = '00:' + currentVal;
}
// If our formatted time is valid, apply it!
if (isValid.time(formattedVal)) {
scope.$applyAsync(function () {
ngModel.$viewValue = formattedVal;
ngModel.$render();
});
}
});
}
}
}());
以及关联的视图:
<div ng-controller="TestController as test">
<input type="text"
maxlength="5"
placeholder="HH:mm"
ng-model="test.startTime"
format-as-time>
<button ng-click="test.getStartTime()">Get Start Time</button>
</div>
以及关联的控制器:
(function () {
'use strict';
angular
.module('app.testModule')
.controller('TestController', TestController);
function TestController () {
var vm = this;
vm.startTime = '';
vm.getStartTime = function () {
console.log(vm.startTime);
}
}
}());
目前,该指令在视图中按预期工作,但我的控制器中的模型未更新,即输入将包含 01:15 但模型将 console.log()
115.
我试过使用:
scope: {
ngModel: '='
}
在指令中,但这并没有做任何事情。
我这样做的方式是否正确?如果是,我需要添加什么以确保模型和视图保持同步?
如果我做错了,正确的最好方法是什么?
问题在于这一行 ngModel.$viewValue = formattedVal;
Angular 有一个用于设置模型值的管道,其中包括 运行 通过注册的 $parsers 和 $validators 对其进行设置。设置值的正确方法是调用 $setViewValue(formattedVal)
,这将 运行 通过此管道的值。