我有一个选项选项。我想初始化关于记录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>
答案 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 。
关于上述实施的几点注意事项:
我选择命名我的指令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
)并将其作为属性添加到元素中。
由于restrict: 'A'
到期(或感谢),如果控件未绑定到require: '?ngModel'
,控件将被忽略。
由于我们的指令扩充了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];
错误标志将被设置,表单将无效,反之亦然。