1

我有一个带有选项的选择。我想初始化关于用户登录的选择值ng-init="own = credentials.user_id"

它在user_id等于 中的值时起作用select。但是当它不等于时,选择的值是"?"。所以应该没有错误

我不想选择这个"?"并使表格无效。

你有解决方案吗 ?

<div ng-class="{ 'error-select': myForm.lead.$error.required == true }"><span>Leader</span></div>

<select ng-model="lead" name="lead" ng-options="leader.user_id as leader.user_display_name for leader in leaders" ng-init="lead = credentials.user_id" required></select> 

<div ng-class="{ 'error-select': myForm.own.$error.required == true }"><span>Leader</span></div>

<select ng-model="own" name="own" ng-options="own.user_id as own.user_display_name for own in owns" ng-init="own = credentials.user_id" required></select> 

输出:user_id = 4

  <select t ng-model="lead" name="lead" ng-options="leader.user_id as leader.user_display_name for leader in leaders" ng-init="lead = credentials.user_id" required="" class="ng-pristine ng-valid ng-valid-required">
   <option value="0">Alexandre</option>
   <option value="1">Antoine</option>
   <option value="2">Zaaza</option>
   <option value="3">toro</option>
   <option value="4"selected="selected">Steffi</option>
  </select>

  <select t ng-model="own" name="own" ng-options="own.user_id as leader.user_display_name for own in owns" ng-init="own = credentials.user_id" required="" class="ng-pristine ng-valid ng-valid-required">
   <option value="?" selected="selected"></option>
   <option value="1">Alexandre</option>
   <option value="2">Steffi</option>
  </select>
4

2 回答 2

3

这个要求并不是那么微不足道,并且可以有几种方法来解决它。(我不确定选择的那个是最好的。)

TL;DR
这是工作演示


这是怎么回事 ?

首先要做的事情是:我们需要了解实际发生的情况。
控件的有效性状态 ( $valid/ $invalid) 取决于$modelValueor $viewValue。这里的关键点是不依赖于元素的实际value属性。

当您尝试将 设置$modelValue为不在users数组中的内容(例如 3)时,即没有<option>可用的有效元素,那么 Angular 会将$modelValueand设置$viewValue为 3,但<select>'value将是?(如果您没有添加一个空<option>元素)或任何明确添加的空值<option>

但是由于验证不是基于元素的,所以从一个角度来看,value一切似乎都是如此。$validrequired


一个解法

一种解决方案是创建一个自定义指令,该指令可以访问元素ngModelController并将自身“挂钩”到$render()函数。
该指令将检查元素是否value?(表示无效$modelValue),如果是,则将$modelValue/设置$viewValue为实际为空的内容,这将正确更新控件的有效性(即无效$modelValue将触发我们的指令的处理程序将其重置为空的内容并且该required约束将不会被满足)。

这是代码:

app.directive('select', function () {
    return {
        restrict: 'E',
        require: '?ngModel',
        priority: 10,
        link: function postLink(scope, elem, attrs, ctrl) {
            if (!ctrl) { return; }
            var originalRender = ctrl.$render.bind(ctrl);
            ctrl.$render = function () {
                originalRender();
                if ((elem.val() === '?') && !ctrl.$isEmpty(ctrl.$modelValue)) {
                    ctrl.$setViewValue(undefined);
                }
            };
        }
    };
});

另请参阅这个简短的演示


关于上述实现需要注意的几点:

  1. 我选择命名我的指令select,以便将其应用于所有选择元素(与本机 Angularselect指令一起 - 是的,这是可能的)。如果您希望仅将其应用于特定控件,则重命名它,将其限制为属性 ( restrict: 'A') 并将其作为属性添加到您的元素中。

  2. 由于(或感谢)require: '?ngModel',如果控件未绑定到 ,它将被忽略ngModel

  3. 由于我们的指令扩充了ngModelController.$render()select指令定义的方法(以优先级 0 执行),我们需要强制指令的链接函数在指令之后select执行。因此,它需要更高的优先级,因为“链接后功能以相反的 [优先级] 顺序运行”。.

于 2014-05-23T13:22:11.927 回答
0

如果您使用ng-required,那么 angular 将为您完成任务。因此,当 ng-required 为 select 设置为 true 时,如果未为 select 设置任何值,则表单中该模型的 $error.required 将设置为 true。

<select ng-model="lead" name="lead" ng-options="leader.user_id as leader.user_display_name for leader in leaders" ng-init="lead = credentials.user_id" ng-required="true"></select> 

请找到相同的小提琴。如果您在脚本中注释代码

$scope.credentials=$scope.leaders[0];

错误标志将被设置,表单将无效,反之亦然。

于 2014-05-23T13:30:51.380 回答