【问题标题】:In Angular, how to get a form in $scope in controller?在 Angular 中,如何在控制器的 $scope 中获取表单?
【发布时间】:2016-08-30 18:28:32
【问题描述】:

拥有这两个文件:

HTML:

<form name="registrationForm" ng-submit="registerUser()">
   ...
</form>

JS(在 Angular 控制器内部):

$scope.registrationForm.confirmPassword.$setValidity("PasswordsMatch", $scope.validation.doPasswordsMatch);

我收到Cannot read property 'confirmPassword' of undefined的错误

这让我相信我无法访问控制器中的registrationForm 表单。基于此 (https://docs.angularjs.org/api/ng/type/ngModel.NgModelController) 我想我应该这样做。

我见过的其他解决方案包括在提交表单时将表单传递给控制器​​,但我需要做的事情(设置自定义验证)需要在此之前发生。

其他解决方案提到通过ng-controller 将控制器添加到表单中,但这并没有改变。

编辑: 从上面的网站看,是不是有原因,为什么在这里(https://plnkr.co/edit/ZT0G6ajdbescT72qLKSU?p=preview)$scope.myForm 可以访问,但只能在$scope.setEmpty 函数内部?

【问题讨论】:

  • &lt;form form="registrationForm" ng-submit="registerUser()"&gt; 应该是&lt;form name="registrationForm" ng-submit="registerUser()"&gt;,名称是表单标签的有效属性
  • 抱歉,原来是name,而不是form。刚刚解决了这个问题。

标签: javascript angularjs angularjs-scope


【解决方案1】:

我建议为此使用控制器本身而不是 $scope 提供程序。这是我在使用 angularjs 时遇到的第一个问题

在您的控制器中:

function MyController($scope) {
  var vm = this;
  vm.registrationForm.confirmPassword.$setValidity("PasswordsMatch", $scope.validation.doPasswordsMatch);
}

在您的表单中:

<form name="vm.registrationForm" ng-submit="registerUser()">
   ...
</form>

唯一的问题是您需要在路由或 ngInclude 中指定 controllerAs 属性:

ng-include="templates/my-template.html" ng-controller="MyController as vm"

when('/my-route', {
  templateUrl: 'templates/my-template.html',
  controller: 'MyController as vm'
 })

【讨论】:

  • 我们必须使用变量vm 有什么原因吗?我们可以做this.registrationForm...吗?
  • 此外,我在您的 sn-ps #1、#2 和 #4 中执行了步骤(我在路由器中设置了控制器),但仍然出现相同的错误。
  • 您必须确保在引用您的模板时使用controllerAs,否则它将不起作用。您也许可以使用this,但这是不好的做法,因为this 是上下文相关的,并且会根据使用位置而改变含义
  • 您不必使用vm,但它是首选名称。查看此风格指南:github.com/johnpapa/angular-styleguide
  • 我设置控制器的那一行是... controller: 'RegistrationController as vm'...这不是你设置控制器的方式吗?
【解决方案2】:

你需要给表单元素添加一个name属性。

<form name="registrationForm" ng-submit="registerUser()">
   ...
</form>

【讨论】:

  • 原来是name,写问题的时候一定不小心改了。刚刚修好了,谢谢指出。
【解决方案3】:

这种形式确实必须依赖于控制器。请看示例:

angular.module("fooApp",[]);

angular.module("fooApp")
  .controller("formctl",function(){
    this.user={};
    this.dosave=function(){
      if(this.user.pwd == this.user.confpwd)
        alert(this.user.username+" logged");
      else
        alert("pwd does not match");
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="fooApp">
  <h1>sample</h1>
  <div ng-controller="formctl as ctl">
    <form ng-submit="ctl.dosave()">
      <label>username</label><br/>
      <input ng-model="ctl.user.username" required/><br/>
      <label>password</label><br/>
      <input ng-model="ctl.user.pwd" type="password" required/><br/>
      <label>confirm password</label><br/>
      <input ng-model="ctl.user.confpwd" type="password"/><br/>
      <input type="submit"/>
    </form>
  </div>
</div>

【讨论】:

    【解决方案4】:

    您需要将表单传递给提交函数以将整个表单传递给控制器​​。使用表单名称。

    <form name="registrationForm" ng-submit="registerUser(registrationForm)">
    ...
    </form>
    

    另一种选择是将输入作为参数直接传递

    <form name="myForm" novalidate >
      some input: <input type="text" name="sometext" ng-model="myInput">
      <input type="submit" ng-click="doAction(myInput)">
    </form>
    

    快速插入 https://plnkr.co/edit/s0Al2LTHkvUPoLYNzTpm?p=info

    如果您只是在输入的值之后,则更容易测试您是否在方法上具有您期望的显式参数,而不是在整个表单中转储。

    【讨论】:

    • 这就是我现在正在做的事情,但我想实现实时验证,而不是仅在用户提交表单时进行的验证。
    • @SammyI。看看这是否适合你。甚至还包括一个笨拙的东西。 odetocode.com/blogs/scott/archive/2014/10/13/…
    猜你喜欢
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 1970-01-01
    • 2017-11-01
    相关资源
    最近更新 更多