我有以下表格:
<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>
&#13;
选择默认选项框是异步加载的:
/* @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' }];
});
}
...
&#13;
问题是当表单呈现时,&#39;保存&#39;即使模型&#39; vm.selectedGroup&#39;正确加载并显示。如果我对结果进行硬编码,一切正常。 看起来像是必需的&#39;属性在返回promise之前评估输入选项。 我也读到了&#39;要求&#39;异步调用的属性仅在首次选择选项后进行评估。
所以我的问题是使用&#39; $ invalid&#39;的正确方法是什么? &#39;需&#39;默认值是异步加载的,用于&#39; md-select&#39;元件。
答案 0 :(得分:0)
这个问题有两个解决方案,如果Angular专家可以解释为什么第一个有效,我会很高兴。
解决方案1: 看起来只是改变阵列初始化的方式就足以满足“所需”的要求。选项。
请参阅&#39; vm.selectedGroup = null; &#39;和&#39; vm.selectedGroup = []; &#39;
/* @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;
});
}
&#13;
解决方案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();
}
};
}
};
}
}());
&#13;
客户端使用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>
&#13;
它工作正常,但复杂性是十倍!