Javascript ngModelController.$setViewValue是否需要在1.3.x上用scope.apply包装
我做了一个编写自定义表单指令的小实验。 基于中的custom form指令示例,我试图指出,您必须将Javascript ngModelController.$setViewValue是否需要在1.3.x上用scope.apply包装,javascript,angularjs,angularjs-directive,angularjs-scope,Javascript,Angularjs,Angularjs Directive,Angularjs Scope,我做了一个编写自定义表单指令的小实验。 基于中的custom form指令示例,我试图指出,您必须将$setViewValue调用包装为范围。$apply,并说明没有它,模型是如何更新的。但令我惊讶的是,我删除了范围。$apply包装,代码仍然有效。 因此,我对angular源代码进行了一些挖掘,发现随着对支持1.3 ngModelOptions的更改,$setViewValue已经调用了范围。$apply,现在实际包装它会导致额外的不必要的摘要周期。 以下是angular 1.3.15的实现源
$setViewValue
调用包装为范围。$apply
,并说明没有它,模型是如何更新的。但令我惊讶的是,我删除了范围。$apply
包装,代码仍然有效。
因此,我对angular源代码进行了一些挖掘,发现随着对支持1.3 ngModelOptions的更改,$setViewValue
已经调用了范围。$apply
,现在实际包装它会导致额外的不必要的摘要周期。
以下是angular 1.3.15的实现源代码:
this.$setViewValue = function(value, trigger) {
ctrl.$viewValue = value;
if (!ctrl.$options || ctrl.$options.updateOnDefault) {
ctrl.$$debounceViewValueCommit(trigger);
}
};
this.$$debounceViewValueCommit = function(trigger) {
var debounceDelay = 0,
options = ctrl.$options,
debounce;
if (options && isDefined(options.debounce)) {
debounce = options.debounce;
if (isNumber(debounce)) {
debounceDelay = debounce;
} else if (isNumber(debounce[trigger])) {
debounceDelay = debounce[trigger];
} else if (isNumber(debounce['default'])) {
debounceDelay = debounce['default'];
}
}
$timeout.cancel(pendingDebounce);
if (debounceDelay) {
pendingDebounce = $timeout(function() {
ctrl.$commitViewValue();
}, debounceDelay);
} else if ($rootScope.$$phase) {
ctrl.$commitViewValue();
} else {
$scope.$apply(function() {
ctrl.$commitViewValue();
});
}
})
这里是没有范围的。$apply
包装器
那么我是否遗漏了什么,或者我是否需要更新他们的文档?
在这种情况下,有人能想出使用
范围$apply包装的理由吗?下面是一个使用ngModellController的表单验证程序示例
并且不使用$scope。$apply
(function(angular)
{
var directive = function()
{
return {`enter code here`
require: 'ngModel',
link: function($scope, iElm, iAttrs, controller) {
// controller.$parsers.push(function(viewValue){
// if (moment( viewValue).isValid()) {
console.log($scope);
controller.$validators.formDateValidator =
function(modelValue, viewValue)
{
return moment( viewValue).isValid();
};
// return viewValue;
//} else {
// controller.$setValidity('form-date-validator', false);
// return undefined;
//}
}
};
}
angular.module('ToDoListApp').
directive('formDateValidator',
[directive]);
}(window.angular));
我没有遗漏任何东西,从1.3开始就没有必要调用scope.$apply。实际上,我提出了一个拉取请求来修复这个示例,它被接受并合并了。我在官方文档中没有看到在$apply中提到要将其包装的地方?示例是包装。。。是的,但是验证没有理由调用$apply,因为它无论如何都不会更新模型。设置有效性并让angular完成表单验证所做的所有工作,因为除非验证过程成功验证数据,否则不会更新模型。但是,上面的注释代码(解析器部分)来自angular版本1.2,而未注释代码($validator)来自angular版本1.3。在这两种情况下,您都不会看到任何$scope。$apply,我认为他们使用$scope的原因。$apply在上面的示例中,这是因为使用了$timeout,并且您无法确定模型更新是否会导致应用摘要循环。