我的主窗体中有一组嵌套子表单(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 );
答案 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。)
如果你在有效计数相同的情况下也改变了图表,那么你必须提出一点不同的逻辑,但原理是一样的。