Angularjs 角度-在控制器和控制器测试中使用表格

Angularjs 角度-在控制器和控制器测试中使用表格,angularjs,Angularjs,文档指定您可以将表单公开到名称为的范围中。假设我有这个表格: <form name="myForm" ng-submit="submit()"> <input type="text" ng-model="somemodel"/> <button ng-submit="submit()"></button> </form> 它们都因未定义而失败。这是怎么做到的?最后,我还要从控制器调用$setPristine。但我就是找不到表格

文档指定您可以将表单公开到名称为的范围中。假设我有这个表格:

<form name="myForm" ng-submit="submit()">
  <input type="text" ng-model="somemodel"/>
  <button ng-submit="submit()"></button>
</form>
它们都因未定义而失败。这是怎么做到的?最后,我还要从控制器调用$setPristine。但我就是找不到表格藏在哪里。他是否可供控制器使用或仅在视图范围内使用

使用角度1.2.5

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

另一个编辑:在分叉建议后,我发现表单在提交之前不存在于$scope上,但在提交之后确实存在。 因此,我猜一个精确的问题应该是:这是预期的行为吗?在ctrl而不是指令中是否有解决方法

如果这是预期的,并且没有解决方法,那么我将把自定义验证检查移到特定的指令中-因为在指令中,如果它们需要:^表单,则在提交之前可以使用该表单。 谢谢


这个问题的答案似乎是当表单被添加到范围中时。从Plunders中可以明显看出,不是在开始时,而是在加载父Ctrl后附加的。我们能控制装货顺序吗?我不知道。似乎这种表单作用域操作的位置应该是一个指令,而不是ctrl键。您可能无法在控制器$scope上看到表单的一个原因是,您的表单是否位于引入新子作用域的指令内。e、 g.如果表单位于ng if或ng开关内

换句话说,在下面的示例中,myForm最终被发布到ng if引入的子范围,而您将无法在MyController$scope上看到它

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

请看这段egghead.io视频,它很好地解释了这一点:

Oops。只要重新阅读您的问题,并意识到您使用了错误的范围路径。正如Matt已经指出的,表单将被pusblished为$scope.myForm,而不是$scope.form.myForm。

如果您将引用从$scope.form更改为$scope.myForm,则定义为,如中所示。除非您有一个名为myForms的父表单(您没有提到),否则您将无法以$scope.myForms.myform的身份访问它

编辑:精练的问题询问当控制器第一次运行时,窗体的父控制器上是否存在未定义窗体的预期行为。答案是肯定的,直到后来才添加

这个问题表明,只有在提交表单时才定义表单。这不太准确。表单被添加到前面的作用域中:提交函数没有任何特殊之处。您应该能够非常愉快地调用表单函数来响应其他按钮的按下。在父控制器中,您可以

$scope.makeTheFormPristine = function() {
  $scope.myForm.$setPristine();
}
从以下几点可以看出:

编辑:从注释中,如果希望父范围中的变量(如通知)依赖于窗体的属性,可以设置手动观察程序:

$scope.$watch('myForm.$pristine', function(newValue, oldValue) {
  if (newValue) {
    $scope.notification = 'Pristine';
  } else {
    $scope.notification = 'Not pristine'
  }
});
你可以在网站上看到这个。但是,我会小心一点,不要在控制器中放入太多的视图逻辑。它可以更好地放在模板中,也可以放在自定义指令中。这可能超出了这个问题的范围,而且可能更好


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

我希望$scope.myForm可以工作。能否显示更多控制器代码/ng控制器html?此外,表格标签中的ng submit=submit应该是ng submit=submit.-1您的示例显然是错误的,您没有解决问题@alonisser$scope.form.myForm.$dirty不符合Matt的说明。如果这不是您需要给我们更多标记的问题,那么我们可以确定这是否是一个chid范围问题。因为正如您所看到的,人们现在正试图猜测您的代码可能仍然有什么问题,所以提供一个plunk/JSFIDLE和一个最小的非工作样本是必不可少的。通过这样做,您还可以增加解决问题的机会quicker@nix好了,这不是子范围问题-ng show不应该创建子范围其余的是旧标记,这不是问题,只是提取了一个非常简单的示例,可能在键入时出错了一两次,我知道if子句是错误的,正如我在代码中所说的,我所能想到的每个变量的控制台日志都是未定义的。表单标记中没有ng控制器。控制器由ui路由器视图连接。我可以从表单访问控制器作用域,当然控制器会随表单模型更新。@nix我试图解决的问题是如何从ctrl键访问表单属性和方法,如$dirty和$pristine。我有一个解决方法,通过提交函数传递它,但这是一个丑陋的黑客,我可能会在一个专门的指令中使用它,当需要表单指令时,它确实有效。我尝试了这两种方法。。奈特
她的工作,也许是关于孩子的范围写在下面,这是在一个ng秀。我将检查这是否应该创建子范围。我想updateng show不会创建作用域,所以我怀疑这是问题所在:Thx@jonc,我当时正在发疯,试图理解为什么我的表单没有显示在$scope上!或然后使用$scope.myStuff={};没有必要。控制器中的访问权仅由$scope.myformi实现。如果这不是正确答案,那么如果您能够或创建自己的,这将非常有帮助,这将显示出@vucalur.Michal的评论中所建议的实际问题。Michal已证明能够使用此plunker从控制器中访问FormController,因此,问题不在粘贴在原始问题中的代码段内。@MichalCharemza我用分叉来显示问题。要优化-问题似乎是表单只有在提交后才存在,如果我以前为表单创建了控制台日志,它就不存在。@ALONISER在父控制器运行后,表单的控制器被添加到父控制器的作用域中,因此console.log将返回未定义。除了console.log,在运行父控制器时,您希望对表单做什么?@MichalCharemza假设我有一个用例-根据提交前的验证状态向用户显示不同的消息,或者执行一些需要服务器检查可用用户名的预验证。我知道我可以用指令来做,但我想更好地理解这种行为。在I console.log的这个fork中,在一个超时内将表单记录在作用域上,以使它在Ctrl运行之后运行,是的,它确实存在。所以我会接受你的回答。
$scope.myStuff = {};
$scope.makeTheFormPristine = function() {
  $scope.myForm.$setPristine();
}
$scope.$watch('myForm.$pristine', function(newValue, oldValue) {
  if (newValue) {
    $scope.notification = 'Pristine';
  } else {
    $scope.notification = 'Not pristine'
  }
});