【问题标题】:ng-disabled doesn't work with md-select asynchronous default valueng-disabled 不适用于 md-select 异步默认值
【发布时间】:2017-03-13 23:31:43
【问题描述】:

我有以下表格:

<form name="editUserForm" ng-cloak="">
<md-input-container layout-margin>
        <label>Available Groups</label>
        <md-select id="groups" ng-model="vm.selectedGroup" ng-model-options="{ trackBy: '$value.id' }" md-on-close="vm.clearGroupSearchTerm()"
          data-md-container-class="selectdemoSelectHeader" multiple required>
          <md-select-header class="demo-select-header">
            <input id="searchGroup" ng-model="vm.groupSearchTerm" type="search" placeholder="Search available groups" class="demo-header-searchbox md-text"
            ng-keydown="$event.stopPropagation()">
          </md-select-header>
          <md-optgroup label="Groups">
            <md-option ng-value="group" ng-repeat="group in vm.groups |filter:vm.groupSearchTerm">{{group.name}}</md-option>
          </md-optgroup>
        </md-select>
      </md-input-container> 

      <div layout="row" layout-align="end">
        <md-button id="buttonCancel" class="md-raised md-primary" ui-sref="search.users" type="submit">Cancel</md-button>
        <md-button id="buttonSave" class="md-raised md-primary" ng-disabled="editUserForm.$invalid" ng-click="vm.addOrUpdateUser()"
          type="submit">Save</md-button>
      </div>
    </div>
  </div>
</form>

选择默认选项框是异步加载的:

  /* @ngInject */
  function UserController($scope, $state, $stateParams, $element,
    usersService, groupsService, groupNameRegex, logger) {
    var vm = this;
    editUser()
    function editUser() {
        usersService.getUser($stateParams.userId).
        then(function (data) {
          vm.user = data;
          for (var i = 0; i < data.userGroups.length; i++) {
            vm.selectedGroup.push(data.userGroups[i].group);
          }
          // vm.selectedGroup = [{ id: 101, name: 'group1' }];
        });
   }
...        

问题是当表单呈现时,即使模型“vm.selectedGroup”已正确加载和显示,“保存”按钮也会被禁用。如果我对结果进行硬编码,一切正常。 看起来“必需”属性在返回承诺之前评估输入选项。 我还读到,异步调用的“必需”属性仅在第一次选择选项后才会评估。

所以我的问题是使用 '$invalid' 'required' 并为 'md-select' 元素异步加载默认值的正确方法是什么。

【问题讨论】:

  • 如果我理解的话,当你设置// vm.selectedGroup = [{ id: 101, name: 'group1' }]; 时它可以工作,对吧?
  • 没错。

标签: angularjs


【解决方案1】:

这个问题有两种解决方案,如果 Angular 专家能解释为什么第一个有效,我会很高兴。

解决方案 1: 看起来仅仅改变数组的初始化方式就足以满足'required'选项。

参见 'vm.selectedGroup = null;' 和 'vm.selectedGroup = [];'

  /* @ngInject */
  function UserController($scope, $state, $stateParams, $element,
    usersService, groupsService, groupNameRegex, logger) {
    var vm = this;
 
    vm.selectedGroup = null;
    
    function editUser() {
      getUserGroups(vm.customerId);
      usersService.getUser($stateParams.userId).
        then(function (data) {
          vm.user = data;
          vm.selectedGroup = [];
          for (var i = 0; i < data.userGroups.length; i++) {
            vm.selectedGroup.push(data.userGroups[i].group);
          }
          vm.selectedStatus = { code: data.enabled, name: '' };
          vm.selectedRole = data.authority;
        });
    }

解决方案 2: 按照关于异步验证的 Angular 示例,我创建了以下指令:

(function () {
  'use strict';

  angular
    .module('app.groups')
    .directive('groupRequired', groupRequired);

  /* @ngInject */
  function groupRequired(usersService, $stateParams, $q) {
    return {
      require: 'ngModel',

      link: function (scope, element, attributes, ngModel) {
        ngModel.$asyncValidators.groupRequired = function (modelValue, viewValue) {
          var selectedGroup = scope.vm.selectedGroup;
          var def = $q.defer();
          if (modelValue.length === 0 && selectedGroup.length === 0) {
            return usersService.getUser($stateParams.userId).
              then(function (data) {
                if (data.userGroups.length > 0) {
                  ngModel.$setValidity('async', true);
                } else {
                  ngModel.$setValidity('async', false);
                }
              });
          } else {
            if (modelValue.length > 0) {
              ngModel.$setValidity('async', true);
            } else {
              ngModel.$setValidity('async', false);
            }
            return $q.resolve();
          }
        };
      }
    };
  }
}());

客户端使用group-required而不是required:

<form name="editUserForm" ng-cloak="">
<md-input-container layout-margin>
        <label>Available Groups</label>
        <md-select id="groups" ng-model="vm.selectedGroup" ng-model-options="{ trackBy: '$value.id' }" md-on-close="vm.clearGroupSearchTerm()"
          data-md-container-class="selectdemoSelectHeader" multiple group-required>

它工作正常,但复杂性是十倍!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-28
    • 2015-08-09
    相关资源
    最近更新 更多