AngularJS在$ valid中观察一组ngForm引用以进行更改

时间:2014-10-31 07:59:04

标签: javascript angularjs watch

我的主窗体中有一组嵌套子表单(ngForm)。通过将每个子表单推送到一个数组,每个子表单都注册到我的表单服务,每个子表单代表一个文档包(整个数组)中的单个文档。我正在使用Google Charts构建进度指令,我想知道其中一个子表单何时变为$ valid。

我已经查看了$ watch,并且知道我可以通过将第三个参数设置为true来深入观察,以便将数组中的任何更改通知给子表单的有效性。这是最好的方法吗?可能发生的深层变化可能是任何事情,而且看起来很昂贵。我可以只看subFormArray [index]。$对更改有效吗?

$scope.$watch('subFormsArray', 
    function( newSubFormsArray, oldSubFormsArray, scope ){
        // loop through newSubFormsArray and check $valid on each index
        // to get new number of completed subforms for progress directive
    }, true);

我也可以在每个子表单上设置一个监视。$使用函数有效,任何更改都会更新进度表。

for( var i = 0; i < $scope.subFormsArray; i++ ) {
    $scope.$watch( function() {
        return $scope.subFormsArray[i].$valid;
    },
    function( newValidity, oldValidity ) {
        // loop through newSubFormValidityArray and check $valid on each index
        // to get new number of completed subforms for progress directive
    });
}

也许使用$ watchGroup?从文档中我无法弄清楚,但似乎可以说我可以这样做:

$scope.$watchGroup( function() {
    var subFormValidity = [];
    for( var i = 0; i < $scope.subFormsArray; i++ ) {
        // create validity array
        subFormValidity.push( $scope.subFormsArray[i].$valid );
    }
    return subFormValidity;
},
function( newSubFormValidityArray ) {
    // loop through newSubFormValidityArray and check $valid on each index
    // to get new number of completed subforms for progress directive
}); 

这会工作吗?哪种解决方案是最佳选择?

更新 使用第一个选项我似乎无法让手表处理形式有效性的变化,任何想法为什么它不起作用?使用console.log我可以看到它被点击了一堆,并正确初始化,但之后它没有被触发。但是如果我对更新功能进行硬编码,那么图表就会被正确设置,因此只是$ watch会导致问题。

$scope.$watch( function() {
     return FormService.getSubForms();
}, function ( newSubForms, oldSubForms ) {

    // Total forms available, and default amount of valid subforms
    var totalForms = FormService.getSubForms().length;
    var totalValid = 0;

    // Check subforms for changes to validity
    angular.forEach( newSubForms, function( subForm, key ) {

        if( subForm.$valid ) { 
            totalValid++; 
        }
    });

    // Update number of complete, and incomplete forms
    self.updateChartData( totalValid, totalForms-totalValid );
}, true );

FINAL 有了它的工作,创建了一个基于子表单有效性的表达式数组,而不是直接从我的服务传递一个子表单数组,我相信这是@PinhasHouri所说的?不知道为什么它没有按照第一种方式工作,因为我正在深入观察。有谁能解释为什么?无论哪种方式都有效。

$scope.$watch( function() {

     var subforms = [];

     angular.forEach( FormService.getSubForms(), function( subform, key ) {
          this.push( subform.$valid );
     }, subforms);

     return subforms;
}, function ( newSubForms, oldSubForms ) {

    // Total forms available, and default amount of valid subforms
    var totalForms = FormService.getSubForms().length;
    var totalValid = 0;

    // Check subforms for changes to validity
    angular.forEach( newSubForms, function( subForm, key ) {

        if( subForm.$valid ) { 
            totalValid++; 
        }
    });

    // Update number of complete, and incomplete forms
    self.updateChartData( totalValid, totalForms-totalValid );
}, true );

1 个答案:

答案 0 :(得分:1)

我会发布这个作为答案,因为在评论中它开始有点太长了。

它与我提议的非常接近,我想这样做:

    $scope.$watch(function() {
       //count how many valids you have
        var totalForms = FormService.getSubForms().length;
        var totalValid = 0;

        // Check subforms for changes to validity
        angular.forEach( newSubForms, function( subForm, key ) {

          if( subForm.$valid ) { 
              totalValid++; 
          }
        });
        return totalValid;
    }, function(newCount, oldCount) {
       self.updateChartData(newCount, totalForms - nowCount);
    });

根据经验,我尽量避免深入观察,因为它会产生深度克隆项目的开销,并在每次观看电话时比较每个项目的 (要了解在应用中调用多少次,请在返回totalValid之前尝试放置console.log。)

如果你在有效计数相同的情况下也改变了图表,那么你必须提出一点不同的逻辑,但原理是一样的。