简单的AngularJS表单在范围中是未定义的

我开始在jsfiddle中使用AngularJS的forms,我已经遇到了一个问题,一个非常简单的表单不能按预期工作。 我所有的是一个命名的forms,它没有出现在某种原因的范围(我期待一个FormController实例)。

我有一个小提琴设置,下面是基本的代码:

HTML

<div id="mainContainer" ng-app="angularTest" ng-controller="MainCtrl"> <h1>The Form</h1> <form name="theForm"> <input name="myName" type="text" ng-model="model.name" /> <input name="submit" type="submit" /> </form> </div> 

JS

 var app = angular.module('angularTest', []); app.controller('MainCtrl', ['$scope', function($scope) { $scope.model = { name: 'Model Name' }; console.log($scope.theForm); //displays 'undefined' }]); 

我无法在jsfiddle上find很多直接的示例,所以我不确定这是否会与像这样的网站发生奇怪的交互(我发现大部分示例都没有使用正式的控制器)。 我已经尝试过Plunker检查,但是我遇到了同样的问题。

我确信我错过了一些非常明显的东西,但我看不到其他很多东西要改变或调整。 任何帮助是极大的赞赏!

控制器初始运行 ,表格只会自行注册到控制器的$scope 。 因此, console.log($scope.theForm)将返回undefined即使一切正确设置。

在你的例子中,对theForm的存在作出反应,你可以在theForm上设置一个监视器来根据它的存在来设置debugging文本:

 $scope.$watch('theForm', function(theForm) { if(theForm) { $scope.formDebugText = 'Form in Scope'; } else { $scope.formDebugText = 'Form is Undefined'; } }); 

可以在http://jsfiddle.net/9k2Jk/1/中看到;

不使用监视(这有点矫枉过正),执行此操作的一个好方法是在范围中定义一个对象,将registry单。

HTML

 <div id="mainContainer" ng-app="angularTest" ng-controller="MainCtrl"> <h1>The Form</h1> <form name="form.theForm"> <input name="myName" type="text" ng-model="model.name" /> <input type="button" value="Here the scope" ng-click="display()"/> <input name="submit" type="submit" /> </form> </div> 

JS

 var app = angular.module('angularTest', []); app.controller('MainCtrl', ['$scope', function($scope) { $scope.model = { name: 'Model Name' }; $scope.form = {}; $scope.display = function () { console.log($scope.form.theForm); } }]); 

对我来说固定的是在$scope上使用父对象。

在控制器中:

 $scope.forms = {}; $scope.registerUser = function registerUser() { if ($scope.forms.userForm.$valid) { alert('submit'); } }; 

在模板中:

 <form name="forms.userForm" ng-submit="registerUser()"> 

原因:

如果您使用<form name="userForm"...而不是<form name="forms.userForm"...它将表单附加到子范围,但是因为$范围使用原型inheritance,只要我声明空的对象文字原来的$范围的forms被附加到它来代替。

这是访问表单variables的推荐方式: https : //docs.angularjs.org/guide/forms – 绑定到表单和控制状态

在HTML中:

 <form name="form"> <input type="button" ng-click="reset(form)" value="Reset" /> </form> 

Youl会将该表格的名称作为variables传递给该函数。

在JS中:

 $scope.reset = function(form) { alert(form); }; 

variables“forms”现在不应该是不确定的。

在尝试使用这行代码访问$ scope.form之前,可以从您的控制器重新初始化表单。 $ scope.form将可用。

 angular.element(jQuery('.form-control')).triggerHandler('input') 

在我的例子中,我使用了ng-include类似于生成另一个子作用域的东西,所以在当前作用域内的属性是undefined ,为了安全并防止子作用域问题,我们应该使用反转variables来命名form.theForm

但是请确保您已经事先在您的控制器中声明了这个表单名称

 <form name="form.theForm"> <input name="myName" type="text" ng-model="model.name" /> <input name="submit" type="submit" /> </form> app.controller('MainCtrl', ['$scope', function($scope) { $scope.model = { name: 'Model Name' }; //You have to declare here, else it will trigger undefined error still. $scope.form = { theForm: {} }; $scope.reset = function(){ $scope.form.theForm.$setPristine(); } }]); 

我写了一个指令来处理这个问题。 它的一个属性,你可以把你的表单,并传递一个函数,将在表单准备好后执行。

使用Javascript

 angular.module('app').directive('formInit', function(){ return { restrict: 'A', scope: { init: '&formInit' }, controller: function($scope, $element){ var name = null; if ($element[0] && $element[0].name){ name = $element[0].name; } var listener = $scope.$watch('init', function(){ if ($scope[name] && $scope.init){ $scope.init(); listener(); } }); } }; }); 

HTML示例

 <form name="test" form-init="testing()"> 

在哪里testing是您的控制器范围的function。