【问题标题】:Do not trigger form.$invalid on first load首次加载时不要触发 form.$invalid
【发布时间】:2015-08-05 08:06:23
【问题描述】:

有这样的形式

    <div ng-controller="FormController as f_ctrl">
    <form ng-submit="f_ctrl.submit()" name="myForm">
    <input type="text" ng-model="f_ctrl.user.username"
            required
            ng-minlength="4"/>
    <input type="text" ng-model="f_ctrl.user.password"/>
    <input type="submit" value="Submit" ng-disabled="myForm.$invalid">
    </form>
</div>

还有这样的控制器

    .controller('FormController', [function() {
    var self = this;

    self.submit = function() {
        console.log('User submitted form with ' + self.user.username)
    }
}]);

我有一个问题:当页面第一次加载时,它会立即在用户名字段上显示红色边框,甚至在我开始输入任何内容之前。 我只需要在第一次提交后突出显示无效字段。这可以使用form.$invalid 来完成吗?

【问题讨论】:

  • 如果是firefox唯一的问题,angular最近在master上修复了它

标签: javascript angularjs forms angularjs-directive angularjs-forms


【解决方案1】:

您必须为此使用 $pristine。当表单控制器没有改变时是真的。因此,当您更改文本框数据时,它会出现错误。

给你的小例子。

<div class="form-group" ng-class="{ 'has-error' : userForm.password.$invalid && !userForm.password.$pristine }">
    <input id="passAnime" type="password" name="password" ng-model="user.password" class="form-control input-md" placeholder="Password" tabindex="5" ng-maxlength="25" ng-minlength="6" required>

    <span ng-show="userForm.password.$dirty && userForm.password.$invalid">
        <p ng-show="userForm.password.$error.required" class="error-messages">
             Your password is required.
        </p>
        <p ng-show="userForm.password.$error.minlength" class="error-messages">
            Your password is too short. Minimum 6 chars.
        </p>
        <p ng-show="userForm.password.$error.maxlength" class="error-messages">
            Your password is too long. Maximum 25 chars. 
        </p>
    </span>
</div>

【讨论】:

  • 你的意思是我需要为我拥有的每个表单字段添加ng-class="{ 'has-error' : userForm.password.$invalid &amp;&amp; !userForm.password.$pristine }"?也许有更好的方法?
  • 是的,我们必须为您要检查验证的每个控制器制作
  • 所以如果我有 50 个字段的表单,我需要为每个字段输入这样的行 ng-class="{ 'has-error' : userForm.field_name.$invalid &amp;&amp; !userForm.field_name.$pristine }" ?
  • 不,但如果你必须动态做,那么你可以在控制器中动态创建整个表单并将表单注入到 html
  • 我想要的是在表单加载时不要在字段周围有红色边框,并且仅在用户开始填写表单时才放置此边框
【解决方案2】:

Angular 有helpers 告诉你表单(或表单域)是$dirty(用户输入了一些东西)还是表单是$touched(在输入上触发了模糊事件)。见this演示。

我只需要在首次提交后突出显示无效字段。

不幸的是,Angular 不支持这一点。但是你可以很容易地自己实现它:

控制器

function FormController() {
  var vm = this;
  vm.submitAttempted = false;
  vm.submit = function(isValid) {
    if (isValid) {
      // do stuff
    }
    else {
      vm.submitAttempted = true;
    }
  };
}

HTML

<div ng-app='app'>
  <div ng-controller='FormController as vm'>
    <form name='fooForm' ng-submit='vm.submit(fooForm.$valid)' novalidate>
      <label>Username</label>
      <input 
        name='username' 
        type='text' 
        ng-model='vm.user.username'
        required
        ng-minlength='4'
        ng-class="{'invalid': vm.submitAttempted && fooForm.username.$invalid}">
      <br /><br />
      <button type='submit'>Submit</button>
    </form>
  </div>
</div>

CSS

.invalid {
  border-color: red;
}

Demo


我有一个问题:当页面第一次加载时,它会立即在用户名字段上显示红色边框,甚至在我开始输入任何内容之前。

这可能是因为您有以下 CSS 类:

.ng-invalid {
  border-color: red;
}

Angular 将始终将 ng-invalid 类应用于无效的字段,您对此无能为力。因此,如果您不总是希望无效字段具有红色边框,则不能使用该类,您应该按照我上面建议的方式进行操作。


另外,请查看ngMessages

【讨论】:

    【解决方案3】:

    您可以通过添加以下 CSS 来禁用默认添加红色边框的输入字段的默认样式:

    input:required {
        -moz-box-shadow: none;
        box-shadow: none;
    }
    

    那么如果要在提交表单时突出显示字段,则需要确保表单和表单字段具有相关的名称属性。这样做将允许您检查该字段是否有效,并在无效时将一个类应用于您的文本字段:

    <input type="text" name="username" ng-class="{ 'invalid-field' : f_ctrl.myForm.username.$invalid && !f_ctrl.myForm.username.$pristine }" required />
    

    f_ctrl.myFormf_ctrl.myform.username 将具有其他属性,您可以使用/检查这些属性来确定表单或字段是否无效,或者是否它们在任何时候都被修改过(例如 f_ctrl.myform.username.$dirty)。您应该能够通过添加以下 HTML 在您的页面上查看这些属性:

    <div>
        <pre>{{f_ctrl.myForm | json}}</pre>
    </div>
    

    或者,您可以将 self.myForm 从控制器输出到控制台以查看其属性

    console.log(self.myForm);
    

    【讨论】:

      猜你喜欢
      • 2020-08-01
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-18
      相关资源
      最近更新 更多