AngularJS表单中的模型值未定义

3

我有两个表单(在同一页中)。第一个表单上有两个按钮,NEXT和BACK。点击NEXT后,将在页面上呈现下一个表单。我使用ng-if来实现这个条件。

<form name="otpform" novalidate ng-if="renderotpform">
  <fieldset ng-disabled="otpdisable">
    <div class="middle-container steps fourth-step overflow-hidden" id="divotp">
      <input class="" type="text" name="otp" placeholder="{{ 'OTP' | translate }}" ng-model="otp" required >
      <input type="button" value="{{ 'BACK' | translate }}" class="brown-button" ng-click="gotoAck()">
      <input type="submit" value="{{ 'NEXT' | translate }}" class="blue-button" ng-click="checkotp()">
    </div>
  </fieldset>
</form>

以下是我的 JavaScript 代码。
 $scope.checkotp = function () {
                debugger;
                var otpvalue;
                $scope.otp = {};
                otpvalue = $scope.otp; //undefined
              }

当我尝试访问otp模型时,我得到了未定义的属性。在之前的表单中,我有下一步按钮。在下一步按钮内部,我有 $scope.renderotpform = true; 所以上面的表单被显示出来了。请问为什么我无法在上述代码中访问OTP?


为什么要这样做?$scope.otp = {}; 这将把 otp 值分配给黑色对象。 - Jenny
我移除了ng-if="renderotpform",现在运行良好。请问我的ng-if哪里有问题? - Niranjan Godbole
当 renderotpform 为 false 或未定义时,它将不会加载包含 otp 文本框的表单。因此,它将不会将 $scope.otp 分配给任何值,实际上它也不会填充 $scope.otp。 - Jenny
让我们在聊天室里继续这个讨论 - Niranjan Godbole
可以使用 ng-show 替代 ng-if,因为后者会从 DOM 中删除内容,而前者只是在条件变为 false 时隐藏它。 - Shashank
显示剩余4条评论
2个回答

2

ng-if创建了它自己的作用域。因此,ng-if中的otp并没有直接绑定到控制器上。您可以将模型绑定到对象或使用controller as语法。强烈建议使用controller as语法, 因为它会隐式地照顾到点规则。

更多信息请查看:

  1. https://github.com/angular/angular.js/wiki/Understanding-Scopes
  2. AngularJs "controller as" syntax - clarification?

var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
  var vm=this;
  vm.renderotpform = true;
  vm.checkotp = function() {
    console.log(vm.otp);
  }
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

<body>

  <div ng-app="myApp" ng-controller="myCtrl as vm">
    <form name="otpform" novalidate ng-if="vm.renderotpform">
      <fieldset ng-disabled="otpdisable">
        <div class="middle-container steps fourth-step overflow-hidden" id="divotp">
          <input class="" type="text" name="otp"  ng-model="vm.otp" required>
          <input type="button" value="BACK" class="brown-button" ng-click="vm.gotoAck()">
          <input type="submit" value="NEXT" class="blue-button" ng-click="vm.checkotp()">
        </div>
      </fieldset>
    </form>
  </div>


1
谢谢你提醒我“ng-if会创建自己的作用域”。 :-) - Gaurav Srivastava
1
您的答案还通过使用对象解决了该问题。当我们使用对象时,绑定将直接发生在父作用域中。 - Vivz
1
是的,我知道,但“ng-if会创建一个子作用域”这一点对我来说是新的。你解释得很好,为什么问题中的代码没有起作用。 - Gaurav Srivastava

1

将表单中所有的ng-model都从一个对象中获取。

这样做是可行的,而且还有其他优点,例如您可以轻松地使用一个对象重置和提交数据。

var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.formData = {};
  $scope.renderotpform = true;
  $scope.checkotp = function() {
    console.log($scope.formData.otp);
  }
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

<body>

  <div ng-app="myApp" ng-controller="myCtrl">
    <form name="otpform" novalidate ng-if="renderotpform">
      <fieldset ng-disabled="otpdisable">
        <div class="middle-container steps fourth-step overflow-hidden" id="divotp">
          <input class="" type="text" name="otp"  ng-model="formData.otp" required>
          <input type="button" value="BACK" class="brown-button" ng-click="gotoAck()">
          <input type="submit" value="NEXT" class="blue-button" ng-click="checkotp()">
        </div>
      </fieldset>
    </form>
  </div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接