Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/415.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ngModelController.$setViewValue是否需要在1.3.x上用scope.apply包装_Javascript_Angularjs_Angularjs Directive_Angularjs Scope - Fatal编程技术网

Javascript ngModelController.$setViewValue是否需要在1.3.x上用scope.apply包装

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的实现源

我做了一个编写自定义表单指令的小实验。 基于中的custom form指令示例,我试图指出,您必须将
$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,并且您无法确定模型更新是否会导致应用摘要循环。