我在ng-repeat中嵌套了一个带有按钮的窗体,其click事件调用的函数包括$ scope。$ broadcast。除了在ng-repeat中每个项目上触发的广播之外,函数中的所有内容都会触发一次。
我无法在重复之外移动按钮,或者我丢失了表单和数据引用。我有一个演示plunker,显示基本设置。如果在其中一个输入中输入值,并在监视控制台时单击“下一步”,则应多次看到广播触发(每个ng-repeat项目一次)。我需要的是一种让广播只触发一次的方法,同时仍然保持对表单的引用,以便根据演示代码进行验证检查。
这是JS,其余的是plunker:
(function () {
var app = angular.module('App', []),
/** manually triggers $validate event to validate the given form */
isFormValid = function ($scope, ngForm) {
var i = null;
//$scope.$emit('$validate');
$scope.$broadcast('$validate');
if(! ngForm.$invalid) {
return true;
} else {
// make the form fields '$dirty' so that the validation messages would be shown
ngForm.$dirty = true;
for(i in ngForm) {
if(ngForm[i] && ngForm[i].hasOwnProperty && ngForm[i].hasOwnProperty('$dirty')) { // TODO: is 'field.$invalid' test required?
ngForm[i].$dirty = true;
}
}
}
};
app.controller('appCtrl', ['$scope', function ($scope) {
$scope.wizardStep = 1;
$scope.nextStep = function () {
var ngForm = $scope['stepForm_' + $scope.wizardStep];
if(isFormValid($scope, ngForm)) { // trigger manual validation
$scope.wizardStep++;
}
};
$scope.prevStep = function () {
$scope.wizardStep--;
};
$scope.submit = function () {
var ngForm = $scope['stepForm_' + $scope.wizardStep]; // we can make this line common
if(isFormValid($scope, ngForm)) {
alert('Form is valid. Submitting...');
}
};
}]);
})();
非常感谢任何帮助或想法,我知道html中的样式和演示代码的其他方面都是禁忌的。我只是做了那些让更快的傻瓜。
TIA
答案 0 :(得分:0)
该事件仅被触发一次。问题是testCtrl正在使用3次,所以它正在捕获事件3次。
您需要为每个步骤创建单独的控制器。如果你真的必须,hack可以在$处理器上去抖动,但我只是在公共服务中用逻辑创建单独的控制器。或者可能是基本控制器和子控制器(它们之间的继承)
答案 1 :(得分:0)
您正在每个模板中重复实例化控制器。您只需要通过使用包含ng-controller指令的div包装表单一次实例化它:
<div ng-controller="testCtrl">
<form name="wizardForm" novalidate="">
<div ng-repeat="step in steps" ng-init="stepForm ='stepForm' + ($index + 1)">
<ng-form name="{{stepForm}}" ng-show="currentStep == $index + 1">
<div ng-include="step.partial"></div>
<div class="form-group wiz-btns">
<div class="col-md-12 text-center">
<button ng-show="currentStep > 1" type="button" class="btn btn-green" ng-click="prevStep()">
<span class="glyphicon glyphicon-circle-arrow-left"></span>
Previous
</button>
<button ng-show="currentStep < steps.length" type="button" class="btn btn-green" ng-click="nextStep(wizardForm[stepForm])">
Next <span class="glyphicon glyphicon-circle-arrow-right"></span>
</button>
<!-- TODO: final submit buton -->
<!--<button></button>-->
</div>
</div>
</ng-form>
</div>
</form>
</div>
从partials中删除指令,所以你就是这样:
<label class="wiz-label" for="title">Step1 Input:</label>
<input type="text" class="form-control" name="step1" ng-model="data.step1" required/>
<span ng-show="stepForm1.$dirty && stepForm1.step1.$invalid" style="background:red;">Input required</span >
答案 2 :(得分:0)
感谢您的回复让我走上正轨。使用状态的整个想法是控制器来自那里,所以将它放在html中将无法满足实际需要。
然而,基于先前的回复,该决议对我来说实际上是一个DUH时刻。我所要做的就是在index.html中改变这一行:
<ng-form name="{{stepForm}}" ng-show="currentStep == $index + 1">
要:
<ng-form name="{{stepForm}}" ng-if="currentStep == $index + 1">
将此更改从 ng-show 更改为 ng-if 仅将子表单和状态(控制器) )一次而不是每一步一次。这适用于使用状态的pluntr和我的rela应用程序。谢谢你带领我这个!