Angular - 使用控制器和控制器测试中的表单

时间:2013-12-15 15:20:31

标签: angularjs

文档指定您可以使用名称将表单公开到范围。所以我可以说我有这种形式:

<form name="myForm" ng-submit="submit()">
  <input type="text" ng-model="somemodel"/>
  <button ng-submit="submit()"></button>
</form>

但我正试图通过控制器$scope.myForm访问该表单并失败:

$scope.submit = function(){
  console.log($scope.myForm) // or form[0] or scope.myForm[0] etc.. 
  if(!$scope.myForm.$dirty){
    //do this and that
  }
//do something
}

它们都因未定义而失败。怎么做的?最后我还想从控制器中调用$setPristine()。但我无法找到表格隐藏的位置。他甚至可以在控制器上使用,还是只在视野范围内使用?

使用角度1.2.5

编辑:当表单名称带点符号时,这也不起作用:myForms.myform

另一个编辑:在分配建议的plunker后,我发现该表单在提交前$scope上不存在,但确实存在之后。 所以我想精炼的问题应该是:这是预期的行为吗?有没有解决方法(在ctrl而不是指令中)?

如果这是预期的并且没有解决方法,那么我将自定义验证检查移动到特定指令 - 因为在指令中(如果它们require:"^form"),表单在提交之前可用。 谢谢!

回答此问题似乎 时将表单添加到作用域。从掠夺者看来,显然不是在开始时,而是在父Ctrl加载后附加。我们可以控制装货单吗?我不知道。似乎这种形式范围操作的地方应该是一个指令,而不是ctrl

3 个答案:

答案 0 :(得分:5)

您可能无法在Controller $scope上看到表单的一个原因是,<form>是否在引入新子范围的指令中。例如如果表单位于ng-ifng-switch

换句话说,在下面的示例中,myForm最终会发布到ng-if引入的子范围,您将无法在MyController $范围内看到它。 / p>

<div ng-controller="MyController">
    <div ng-if="true">
        <form name="myForm"></form>
    </div>
</div>

解决此问题的一种方法是使用点符号将表单发布到对象包装器中,而不是直接将其放在范围内。

<div ng-controller="MyController">
    <div ng-if="true">
        <form name="myStuff.myForm"></form>
    </div>
</div>

MyController中,确保一个对象存在,因此它将发布到它而不是子范围。:

$scope.myStuff = {};

看看这个egghead.io视频做得很好解释:https://www.youtube.com/watch?v=DTx23w4z6Kc

答案 1 :(得分:2)

如果您将引用从$scope.form更改为$scope.myForm,则会定义该引用,如this plunker中所示。除非您有一个您未提及的名为myForms的父表单,否则您将无法以$scope.myForms.myform的形式访问它。

编辑:精确的问题询问在窗体的父控制器上是否存在预期的行为,即在首次运行控制器时表单未定义。答案是肯定的,直到稍后才会添加。

问题表明表单仅在提交表单时定义。这不太准确。在此之前的表单中添加了表单:提交功能没有什么特别之处。您应该可以非常愉快地调用表单函数以响应其他按钮按下。在父控制器中,您可以拥有

$scope.makeTheFormPristine = function() {
  $scope.myForm.$setPristine();
}

从下面的Plunkr可以看出:

http://plnkr.co/edit/dDVrez9UP1GYRIDrUxJs?p=preview

编辑:如果您希望父作用域中的变量(例如notification)依赖于表单的属性,则可以在注释中设置手动监视器:

$scope.$watch('myForm.$pristine', function(newValue, oldValue) {
  if (newValue) {
    $scope.notification = 'Pristine';
  } else {
    $scope.notification = 'Not pristine'
  }
});

您可以在http://plnkr.co/edit/2NMNVAfw8adlpFRGuSoC?p=preview看到此消息。但是,对于将太多“视图”逻辑放入控制器,我会有点小心。它可能更好地放置在模板中,或者可能是自定义指令的事件。这可能超出了这个问题的范围,可能会更好https://codereview.stackexchange.com/

另外:我认为您不需要按钮和表单上的2 ng-submit属性,但我怀疑这与此问题无关。

答案 2 :(得分:1)

糟糕。只需重新阅读您的问题,并意识到您使用的是错误的范围路径。正如马特已经指出的那样,该表格将适用于$scope.myForm而不是$scope.form.myForm