我有以下代码:
<div modal="modal.shouldBeOpen" close="close()" options="opts">
<div class="modal-body">
<form novalidate name="itemForm" style="margin-bottom: 0px;">
包含在modal.html文件中的内容
<div data-ng-controller="AdminController">
<ng-include src="'/Content/app/admin/partials/grid-subject.html'"></ng-include >
<ng-include src="'/Content/app/admin/partials/modal.html'"></ng-include>
</div>
在我的AdminController控制器中,我尝试使用以下代码将表单重置为pristine:
$scope.itemForm.$setPristine();
当我这样做时,它告诉我“itemForm”未定义。
有没有办法可以将表单的内容设置为pristine。我认为这是一个范围问题,但我不知道如何解决它。一世 尝试了一种解决方案,即删除第二个包含并直接粘贴代码。此解决方案有效。
但是我们希望能够重用代码 所以我希望能够使用for modal.html
来做到这一点请注意,我们之所以这样做,是因为我们的modal.html上有以下内容:
<button
class="btn float-right"
data-ng-disabled="itemForm.$pristine"
data-ng-click="modalReset()"
data-ng-show="modal.resetButton">
Reset</button>
</form>
所以我们实际上是在itemForm中,并希望从里面的按钮将它设置为$ pristine。
答案 0 :(得分:9)
这个答案将打破所有规则(即在控制器内部进行DOM遍历),但无论如何它都是......
.controller('AdminController', ['$scope','$element',
function($scope, $element) {
$scope.$on('$includeContentLoaded', function() {
var childFormController = $element.find('form').eq(0).controller('form');
console.log(childFormController);
childFormController.$setPristine();
});
}]);
我们等待加载ng的内容加载,然后从定义了AdminController的$element
中,我们查找form
个元素,选择第一个元素,然后获取它的FormController。
如果您仅因某些用户互动而致电$setPristine()
,则您不会需要查找$includedContentLoaded
事件 - 我只需这样做,因为我没有&#39 ; t想要创建任何UI组件来触发操作,当控制器第一次运行时,表单还没有存在。
另请参阅AngularJS: Access formController of a form placed inside transcluded directive from parent controller,其中涉及尝试从父母访问子女的类似问题。
更清洁的解决方案:定义指令(在ng-include元素上使用它)并将AdminController函数作为属性传递给它。在指令的link函数中,调用该方法并将FormController作为参数传递。然后AdminController将引用所需的FormController。 (我没有费心去编码,因为我不确定你需要一个解决方案,你必须使用指令和ng-include。)
答案 1 :(得分:4)
嗯,一种方法是广播一个事件,如下:
angular.module('myApp',[])
.controller('AdminCtrl',function($scope){
$scope.modalReset = function(){
$scope.$broadcast('modal-reset');
};
})
.controller('ModalCtrl', function($scope){
$scope.$on('modal-reset', function(){
$scope.itemForm.$setPristine();
});
});
这样你就不必穿越dom。
答案 2 :(得分:1)
不要破坏规则:)只需在控制器中定义变量(空对象)并在定义表单时使用它。由于角度JS使用范围原型,当表单将尝试访问内部范围(引导变量)时,它将首先通过范围链并尝试在父范围内找到相同的变量。
<!—- The vars should live in the controller. I placed them here for the example. -—>
<div ng-controller=“controllerName” ng-init="form={}; model={}" >
<div ng-include=“ ‘path-to-the-template’ ”></div>
</div>
<!—- Inside path-to-the-template -—>
<form name="form.createUser">
<input name="name" ng-model="model.name" />
<input name="email" ng-model="model.email" />
</form>
参考链接http://blog.152.org/2014/07/angular-form-element-not-attaching-to.html
答案 3 :(得分:0)
如果你想通过一些用户交互来实现这一点,我认为更简洁,更有棱角的做法是使用自定义指令将表单设置为原始(即用户希望通过按esc或单击按钮或其他任何内容来清除表单。
app.directive("formCleaner",
function () {
return {
restrict: 'E',
require: '^form',
scope: {
callback: '&',
defaultText:'@'
},
template: '<button type="button" ng-click="setFormToPristine()" class="btn btn-warning" >{{defaultText}}</button>',
link: function (scope, element, attrs, formCtrl) {
scope.setFormToPristine = function () {
formCtrl.$setPristine();
scope.callback();
};
}
};
});
并简单地将其连接到表单中的某个按钮:
<form name="testForm">
<input type="text" ng-model="someModel" />
<hr/>
<input type="button" value="submit form" class="btn btn-primary" ng-disabled="testForm.$pristine"
ng-click=submitForm(testForm) />
<form-cleaner callback="resetFormCallback(testForm)" default-text="Clear Form"></form-cleaner>
</form>
如果您希望将表单直接从控制器设置为pristine(不是由于某些用户交互),例如来自POST的成功响应,那么一种方法是为指令分配回调它将负责清除表单,然后从控制器调用该回调。在您看来:
<form-cleaner callback="resetFormCallback(testForm)" default-text="Clear Form"></form-cleaner>
和控制器:
$scope.resetFormOnSubmitCallback=function(cb){
$log.warn("simulating $http POST call.....");
$timeout(function() {
cb();
$scope.someModel=null;
}, 3000)
}
和指令:
return {
restrict: 'E',
require: '^form',
scope: {
callback: '&',
defaultText:'@',
ngDisabled:'='
},
template: '<button type="button" ng-disabled="ngDisabled" ng-click="submitForm()" class="btn btn-primary" >{{defaultText}}</button>',
link: function (scope, element, attrs, formCtrl) {
var setFormToPristine=function(){
$log.log("setting form to prsitine....");
formCtrl.$setPristine();
};
scope.submitForm = function () {
scope.callback({
onFormSubmittedCallback:setFormToPristine
});
};
}
};
请参阅plunk