如何在AngularJS中将<option value =“?”> </option>渲染为错误?

时间:2014-05-23 09:26:56

标签: forms angularjs select angularjs-ng-init

我有一个选项选项。我想初始化关于记录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> 

OUTPUT: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>

2 个答案:

答案 0 :(得分:3)

这个要求不是那么简单,可能有几种方法。 (我不确定所选择的是最好的。)

<强> TL; DR
这是 working demo


发生了什么事?

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

当您尝试将$modelValue设置为不在users数组中的内容(例如3)时,即没有可用的有效<option>元素时,Angular将设置$modelValue$viewValue到3,但<select>的{​​{1}}将value(如果您尚未添加空? element)或任何明确添加的空<option>的值。

但是,由于根据<option>元素验证,从value角度来看,所有内容似乎都是$valid


解决方案

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

以下是代码:

required

另请参阅此 short demo


关于上述实施的几点注意事项:

  1. 我选择命名我的指令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); } }; } }; }); ,因此它将应用于所有选择元素(与原生Angular select指令一起 - 是的,这是可能的)。如果您希望仅将其应用于特定控件,请将其重命名,将其限制为属性(select)并将其作为属性添加到元素中。

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

  3. 由于我们的指令扩充了ngModel方法,该方法由ngModelController.$render()指令定义(优先级为0),我们需要强制执行指令的链接函数 select指令之后。因此,它需要更高的优先级,因为 "post-link functions are run in reverse [priority] order."

答案 1 :(得分:0)

如果您使用 ng-required ,则angular将为您完成任务。 因此,当选择为ng-required设置为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> 

请查找fiddle相同内容。在脚本中,如果您注释代码

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

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