范围内未定义简单的 AngularJS 表单
Posted
技术标签:
【中文标题】范围内未定义简单的 AngularJS 表单【英文标题】:Simple AngularJS Form is undefined in Scope 【发布时间】:2014-04-21 14:29:23 【问题描述】:我开始在 jsfiddle 中使用 AngularJS 表单,我已经遇到了一个问题,即一个非常简单的表单示例无法按预期工作。我所拥有的只是一个命名表单,并且由于某种原因它没有出现在范围内(我期待一个 FormController 实例)。
我设置了fiddle,下面是基本代码:
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 上找不到很多直截了当的例子,所以我不确定这是否是与类似网站的一些奇怪的交互(我发现的大多数例子都没有使用正式的控制器)。我也试过在 Plunker 上检查,但我遇到了同样的问题。
我确定我遗漏了一些非常明显的东西,但我看不出这里有很多其他需要改变或调整的东西。非常感谢任何帮助!
【问题讨论】:
当我的表单嵌套在一个带有 ng-if 的元素中时,我遇到了这个问题。改用 ng-show 解决了这个问题。 【参考方案1】:在我的例子中,我使用ng-include
来生成一个子作用域,所以在当前作用域内属性是undefined
,为了安全和防止子作用域问题,我们应该使用反向变量来命名表单,就像@ 987654323@.
但请确保您已提前在控制器中声明了此表单名称。
<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();
]);
【讨论】:
【参考方案2】:在不使用 watch 的情况下执行此操作的一个好方法(这有点矫枉过正)是在您将注册表单的范围内定义一个对象。
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);
]);
【讨论】:
这可能不是解决此问题的最佳方法,但通常是将表单验证带入控制器的好方法。感谢分享。 注意尝试直接绑定到form
是行不通的,它必须是form.someNewName
。【参考方案3】:
在尝试使用这行代码访问 $scope.form 之前,您可以从控制器重新初始化表单。然后 $scope.form 将可用。
angular.element(jQuery('.form-control')).triggerHandler('input')
【讨论】:
【参考方案4】:为我解决的问题是在 $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"...
,它会将表单附加到子范围,但是因为 $scopes 使用原型继承,所以只要我在原始 $scope 上声明了一个空对象文字,表单就会附加到取而代之。
【讨论】:
所以我将ng-controller="MainCtrl"
添加到form
中,这似乎让它直接绑定到该范围。这种方法有什么问题吗?【参考方案5】:
这是访问表单变量的推荐方法: https://docs.angularjs.org/guide/forms - 绑定到表单和控制状态
在 html 中:
<form name="form">
<input type="button" ng-click="reset(form)" value="Reset" />
</form>
您将表单的名称作为变量传递给函数。
在 JS 中:
$scope.reset = function(form)
alert(form);
;
现在不应未定义变量“form”。
【讨论】:
你将如何测试这个?【参考方案6】:我写了一个指令来处理这个问题。它是一个属性,您可以将其放在表单上并传递一个函数,该函数将在表单准备好时执行。
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
是控制器范围内的一个函数。
【讨论】:
【参考方案7】:表单仅在控制器初始运行之后向控制器的$scope
注册。因此,即使一切设置正确,console.log($scope.theForm)
也会返回 undefined。
在您对theForm
的存在作出反应的示例中,您可以在theForm
上设置一个观察器,以根据其存在设置调试文本:
$scope.$watch('theForm', function(theForm)
if(theForm)
$scope.formDebugText = 'Form in Scope';
else
$scope.formDebugText = 'Form is Undefined';
);
可以在http://jsfiddle.net/9k2Jk/1/看到实际操作
【讨论】:
啊,我早该知道的。我已经处理过这些类型的异步加载行为!谢谢!这一切最终都会沉没;) 如果您只需要在表单报告它存在 var formWatchUnbind = $scope.$watch 然后 if(theForm)formWatchUnbind(); //在这里做你想做的 这对我不起作用。$scope.theForm
始终未定义
@michal :感谢您的回答。仅当控制器完成初始运行时,任何显示“表单”的文档才会注册到控制器范围。会有帮助的。谢谢以上是关于范围内未定义简单的 AngularJS 表单的主要内容,如果未能解决你的问题,请参考以下文章