AngularJs不能访问控制器中的表单对象($ scope)

我正在使用bootstrap-ui更具体的模态窗口。 我有一个模式的表单,我想要的是实例化表单validation对象。 所以基本上我是这样做的:

<form name="form"> <div class="form-group"> <label for="answer_rows">Answer rows:</label> <textarea name="answer_rows" ng-model="question.answer_rows"></textarea> </div> </form> <pre> {{form | json}} </pre 

我可以看到HTML文件中的表单对象没有问题,但是如果我想从控制器访问表单validation对象。 它只是输出我空的对象。 这里是控制器的例子:

 .controller('EditQuestionCtrl', function ($scope, $modalInstance) { $scope.question = {}; $scope.form = {}; $scope.update = function () { console.log($scope.form); //empty object console.log($scope.question); // can see form input }; }); 

什么可能是我不能从控制器访问$scope.form的原因?

只是对于那些不使用$scope ,而是在他们的控制器中,你必须在表单的名字前添加控制器别名。 例如:

 <div ng-controller="ClientsController as clients"> <form name="clients.something"> </form> </div> 

然后在控制器上:

 app.controller('ClientsController', function() { // setting $setPristine() this.something.$setPristine(); }; 

希望它也有助于整体的答案。

如果ng-controller是表单元素的父级,那么正常的方法是:请删除这一行:

 $scope.form = {}; 

如果angular度将表单设置为您的控制器$scope ,则用空对象覆盖它。


正如选举委员会所说的那样,情况并非如此。 他正在使用$modal.open ,所以控制器不是窗体的父窗体。 我不知道一个很好的解决scheme。 但是这个问题可以被破解:

 <form name="form" ng-init="setFormScope(this)"> ... 

并在你的控制器中:

 $scope.setFormScope= function(scope){ this.formScope = scope; } 

后来在你的更新function:

 $scope.update = function () { console.log(this.formScope.form); }; 

看看ui bootstrap的'modal'的源代码,你会看到指令了

 transclude: true 

这意味着模式窗口将创build一个新的子作用域,其父目录是控制器$ scope,作为指令作用域的同级。 然后,“表单”只能由新创build的子范围访问。

一个解决scheme就是在控制器范围内定义一个var

 $scope.forms = {}; 

然后,对于表单名称 ,我们使用像forms.formName1 。 这样,我们仍然可以通过调用$scope.forms.formName1访问控制器。

这是有效的,因为JS中的inheritance机制是原型链。 当子范围试图创buildforms.formName1 ,它首先尝试在自己的作用域中find表单对象,因为它是在飞行中创build的,所以它肯定没有它。 然后它会尝试从父级(直到原型链)find它,因为我们已经在控制器范围中定义了它,所以它使用我们创build的“ forms ”对象来定义variablesformName1 。 因此,我们仍然可以在我们的控制器中使用它来做我们的东西,如:

 if($scope.forms.formName1.$valid){ //if form is valid } 

更多关于跨越,从45分钟看下面的Misco的video。 (这可能是最精确的解释是什么transcluded范围,我已经find了!!!)

http://www.youtube.com/watch?v=WqmeI5fZcho

不需要ng-init的$scope.form ,因为问题在于,在运行控制器代码时,没有设置$scope.form 。 删除form = {}初始化并使用手表访问表单:

 $scope.$watch('form', function(form) { ... }); 

我使用文档化的方法。

https://docs.angularjs.org/guide/forms

所以,用户的表单名称,在“保存”点击例如只是传递formName作为参数,并嘿prestoforms可用保存方法(其中formScopeObject是根据您在表格中设置的ng-models规范或如果你是编辑这将是存储正在编辑的项目,即用户帐户的对象)

 <form name="formExample" novalidate> <!-- some form stuff here --> Name <input type="text" name="aField" ng-model="aField" required="" /> <br /><br /> <input type="button" ng-click="Save(formExample,formScopeObject)" /> </form> 

为了扩大user1338062的答案:一个解决scheme,我已经多次使用我的控制器初始化的东西,但不得不等待,直到它实际上可用:

 var myVarWatch = $scope.$watch("myVar", function(){ if(myVar){ //do whatever init you need to myVarWatch(); //make sure you call this to remove the watch } }); 

对于那些使用Angular 1.5的人来说,我的解决scheme是$ $在$ postlink阶段观看表单:

 $postLink() { this.$scope.$watch(() => this.$scope.form.$valid, () => { }); }