【问题标题】:What are the reasons for ng-disabled not to work when used in a buttonng-disabled在按钮中使用时不起作用的原因是什么
【发布时间】:2015-10-05 11:55:31
【问题描述】:

我有一个 Angular 表单,我在其中进行验证。如果任何必填字段为空并且验证失败,我希望表单不能提交。表格如下。

<form name="userForm" novalidate>
    <fieldset ng-disabled="data.externalUserDisable">
        <div class="restrictwidth">
            <h1 ng-if="data.urlId === 'new'" translate>NewUser</h1>
            <div class="form-group required" ng-class="{ 'has-error' : userForm.username.$invalid && !userForm.username.$pristine }">
                <label class="control-label" translate>UsernameEmail</label>
                <input class="form-control" type="email" id="username" name="username" ng-model="user.Username" ng-model-options="{'update On': 'blur'}" ng-disabled="(!data._editMode && !(user.Status === 'NotVerified' || user.Status === 'ActivationPending'))" ng-maxlength="256" required>
                <div class="error-messages" ng-messages="userForm.username.$error" ng-if="userForm.$submitted || !userForm.username.$pristine">
                    <div ng-message="required" class="help-block error-message"><span translate="UsernameRequired"></span></div>
                </div>
            </div>
            <div class="row">
                <div class="form-group required col-sm-6" ng-class="{ 'has-error' : userForm.firstName.$invalid && !userForm.firstName.$pristine }">
                    <label class="control-label" translate>FirstName</label>
                    <input class="form-control" type="text" id="firstName" name="firstName" ng-model="user.FirstName" ng-maxlength="64" required>
                    <div class="error-messages" ng-messages="userForm.firstName.$error" ng-if="userForm.$submitted || !userForm.firstName.$pristine">
                        <div ng-message="maxlength" class="help-block error-message"><span translate="FirstNameLength"></span></div>
                        <div ng-message="required" class="help-block error-message"><span translate="FirstNameRequired"></span></div>
                    </div>
                </div>
                <div class="form-group required col-sm-6" ng-class="{ 'has-error' : userForm.lastName.$invalid && !userForm.lastName.$pristine }">
                    <label class="control-label" translate>LastName</label>
                    <input class="form-control" type="text" id="lastName" name="lastName" ng-model="user.LastName" ng-maxlength="64" required>
                    <div class="error-messages" ng-messages="userForm.lastName.$error" ng-if="userForm.$submitted || !userForm.lastName.$pristine">
                        <div ng-message="maxlength" class="help-block error-message"><span translate="LastNameLength"></span></div>
                        <div ng-message="required" class="help-block error-message"><span translate="LastNameRequired"></span></div>
                    </div>
                </div>
            </div>               
            <div class="form-group required" ng-class="{ 'has-error' : userForm.masterEngagement.$invalid && !userForm.masterEngagement.$pristine }">
                <label class="control-label" translate>MasterEngagement</label><i ng-show="loadingLocations" class="glyphicon glyphicon-refresh"></i>
                <input type="text" name="masterEngagement" ng-model="user.MasterEngagementId" ng-if="!data.externalUserDisable" typeahead="engagement.EngagementId as engagement.EngagementName for engagement in getLocation($viewValue)" typeahead-on-select='onSelect($item, $model, $label)'
                       typeahead-loading="loadingLocations" typeahead-editable="false" typeahead-input-formatter="formatLabel($model)" typeahead-template-url="customTemplate.html" typeahead-wait-ms="500" class="form-control" ng-disabled="singleEngagementAdmin !== '0'" required>
                <input type="text" name="masterEngagement" ng-model="user.MasterEngagementName" ng-if="data.externalUserDisable" class="form-control" ng-disabled="singleEngagementAdmin !== '0'" required>
            </div>

            ...

            <div class="restrictwidth">
                <button ng-if="data.urlId === 'new'" type="submit" class="btn btn-primary btn-lg pull-right ladda-button" data-style="expand-left" ng-save-in-progress ng-disabled="{{ userForm.$invalid }}" ng-click="insert()" translate>Save</button>
                <button ng-if="data.urlId !== 'new'" type="submit" class="btn btn-primary btn-lg pull-right ladda-button" data-style="expand-left" ng-save-in-progress ng-disabled="userForm.$invalid || (!superUser && user.Superuser)" ng-click="update()"><span class="ladda-label" translate>Update</span></button>                 
                <a class="btn btn-link pull-left" ng-click="back()" type="button"><span class="ladda-label" translate>Cancel</span></a>
            </div>
        </div>
    </fieldset>
</form>

使用 ng-disabled 禁用保存按钮是正确的。但该按钮未被禁用。当表单加载时,按钮不会被禁用,即使是验证错误,按钮也不会被禁用。

我检查了userForm 对象,$invalid 值为真,$valid 值为假。

我想知道发生这种情况的原因是什么。?可能的原因是什么?

更新

打印用户表单的输出表单..

{
  "$error": {
    "required": [
      {
        "$validators": {},
        "$asyncValidators": {},
        "$parsers": [],
        "$formatters": [
          null
        ],
        "$viewChangeListeners": [],
        "$untouched": true,
        "$touched": false,
        "$pristine": true,
        "$dirty": false,
        "$valid": false,
        "$invalid": true,
        "$error": {
          "required": true
        },
        "$name": "username",
        "$options": {
          "update On": "blur",
          "updateOnDefault": true
        }
      },
      {
        "$validators": {},
        "$asyncValidators": {},
        "$parsers": [],
        "$formatters": [
          null
        ],
        "$viewChangeListeners": [],
        "$untouched": true,
        "$touched": false,
        "$pristine": true,
        "$dirty": false,
        "$valid": false,
        "$invalid": true,
        "$error": {
          "required": true
        },
        "$name": "firstName",
        "$options": null
      },
      {
        "$validators": {},
        "$asyncValidators": {},
        "$parsers": [],
        "$formatters": [
          null
        ],
        "$viewChangeListeners": [],
        "$untouched": true,
        "$touched": false,
        "$pristine": true,
        "$dirty": false,
        "$valid": false,
        "$invalid": true,
        "$error": {
          "required": true
        },
        "$name": "lastName",
        "$options": null
      },
      {
        "$validators": {},
        "$asyncValidators": {},
        "$parsers": [
          null
        ],
        "$formatters": [
          null,
          null
        ],
        "$viewChangeListeners": [],
        "$untouched": true,
        "$touched": false,
        "$pristine": true,
        "$dirty": false,
        "$valid": false,
        "$invalid": true,
        "$error": {
          "required": true
        },
        "$name": "masterEngagement",
        "$options": null
      }
    ]
  },
  "$name": "userForm",
  "$dirty": false,
  "$pristine": true,
  "$valid": false,
  "$invalid": true,
  "$submitted": false,
  "username": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [],
    "$formatters": [
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": false,
    "$invalid": true,
    "$error": {
      "required": true
    },
    "$name": "username",
    "$options": {
      "update On": "blur",
      "updateOnDefault": true
    }
  },
  "firstName": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [],
    "$formatters": [
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": false,
    "$invalid": true,
    "$error": {
      "required": true
    },
    "$name": "firstName",
    "$options": null
  },
  "lastName": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [],
    "$formatters": [
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": false,
    "$invalid": true,
    "$error": {
      "required": true
    },
    "$name": "lastName",
    "$options": null
  },
  "title": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [],
    "$formatters": [
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": true,
    "$invalid": false,
    "$error": {},
    "$name": "title",
    "$options": null
  },
  "employeeNumber": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [],
    "$formatters": [
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": true,
    "$invalid": false,
    "$error": {},
    "$name": "employeeNumber",
    "$options": null
  },
  "userInfo": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [],
    "$formatters": [
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": true,
    "$invalid": false,
    "$error": {},
    "$name": "userInfo",
    "$options": null
  },
  "timeZone": {
    "$viewValue": "W. Europe Standard Time",
    "$modelValue": "W. Europe Standard Time",
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [],
    "$formatters": [],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": true,
    "$invalid": false,
    "$error": {},
    "$name": "timeZone",
    "$options": null
  },
  "culture": {
    "$viewValue": "en-US",
    "$modelValue": "en-US",
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [],
    "$formatters": [],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": true,
    "$invalid": false,
    "$error": {},
    "$name": "culture",
    "$options": null
  },
  "policy": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [],
    "$formatters": [],
    "$viewChangeListeners": [
      null
    ],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": true,
    "$invalid": false,
    "$error": {},
    "$name": "policy",
    "$options": null
  },
  "masterEngagement": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [
      null
    ],
    "$formatters": [
      null,
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": false,
    "$invalid": true,
    "$error": {
      "required": true
    },
    "$name": "masterEngagement",
    "$options": null
  }
}

【问题讨论】:

  • 我能猜到的唯一原因是缺少model!需要查看controller或运行代码以便更好地理解问题!
  • 创建一个复制问题的演示。 ng-save-in-progress 是做什么的?使用 ng 前缀命名自定义指令的不良做法通常表示核心功能
  • 你能提供同样的 plunker 吗?
  • @charlietfl ng-save-in-progress 是用于在保存过程中显示微调器图标的指令。
  • 更感兴趣的是它是否会影响ng-disabled。仅供参考 - 对你的国家很好奇......我来自美国,但在 90 年代中期在尼甘布生活了 8 个月,而所有内战都在进行中。希望一切都结束了,事情会更加繁荣

标签: javascript angularjs forms validation angularjs-ng-disabled


【解决方案1】:

实际上,按钮标签一切正常,请查看此演示:http://plnkr.co/edit/fJoq7RLrDNYMxYwh6bPq?p=preview

您的问题是ng-if 指令创建了一个内部范围,但在父范围中声明了表单。在这种情况下,要根据您拥有的表单禁用按钮,您需要从父级访问它。 简化后会是这样:

<button type="submit" ng-disabled="$parent.userForm.$invalid">Save</button>

编辑: 拥有两个ng-if 意味着在这种情况下您必须使用两个父作用域,在原始代码中,拥有一个ng-if 访问无效属性是通过$parent.userForm.$invalid,两个ng-if

<button type="submit" ng-if="data.urlId === 'new'" ng-disabled="$parent.$parent.userForm.$invalid">Save</button>

这可以通过使用ng-showng-hide 而不是ng-if 来避免,不同之处在于前两个不创建内部范围,而每个ng-if 将在其父级内部创建其范围。如果您将两个 ng-if 都更改为 ng-show,则该按钮将与您原来的 ng-disabled="userForm.$invalid" 一起使用。

【讨论】:

  • 添加 $parent 无效。按钮本身有一个 ng-if。我更新了代码。加载表单时,值 userForm.$invalid 为 true。并且当填写必填字段时,它将变为错误。但是由于某种原因,ng-disabled 不起作用。
  • 按钮是否必须在添加了ng-ifs 的元素内才能使子作用域计数增加。像这样div &gt; div &gt; div &gt; button 如果所有 3 个 divs 都有 ng-if 那么计数将为 3。或者即使按钮元素不在这些 div 中,计数仍然是 3?
  • 不要计算 div 或任何其他 html 标签,只计算 ng-ifs,但实际上如果你有 &lt;div ng-if="dffd"&gt;&lt;div ng-if="dffd2"&gt;&lt;div ng-if="dffd3"&gt;&lt;div ng-if="dffd4"&gt;{{$parent.$parent.$parent.$parent.form}}&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;,你将不得不增加 4 个 parrent 范围才能访问外部表单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-04
  • 2018-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多