如何知道选择的ngModel何时引用ngOptions中的未知选项

时间:2014-09-11 08:35:55

标签: angularjs

我有两个基于常见数据集“选项”的级联下拉菜单。第一个选定值过滤第二个选择中可用的选项。

<label for="select1" class="control-label">Select1</label>
<select name="select1" ng-model="select1" ng-options="option.select1 as option.select1 for option in options | unique: 'select1' | orderBy: 'select1'">
</select>

<label for="select2" class="control-label">Select2</label>
<select name="select2" ng-model="select2" ng-options="option.select2 as option.select2 for option in options | filter: {select1: select1} | unique: 'select2' | orderBy: 'select2'">
</select>

当用户更改select1中的值时,select2中已选择的值可能仍然可用,也可能不可用。当select2中的值变为未知时,angular通过在select中选择未知(“?”)val来反映这一点,但它不会更改模型。

问题是我不知道如何确定何时选择了无效值。我想将其设置为null或至少知道该值无效。

我在jsfiddle

中提供了此行为的示例

我尝试创建一个指令来监听视图值更改并在“?”时将模型更改为null已选中,但当角度将视图设置为未知值时,不会触发更改事件。

.directive('known', function() {
    return {
        restrict: 'AC',
        require: ['select', '?ngModel'],
        link: function ($scope, $element, $attrs, ctrls) {

            $element.change(ctrls, function() {
                if ($element.val() == "?")
                    ctrls[1].$setViewValue(null);
            });
        }
    };
 })

感谢您的时间

修改

我可能会过度简化我的问题:通常有5个级联选择彼此绑定。选择(n + 2)取决于select(n + 1)和select(n)。 Select(n)不知道取决于他的选择,例如select(n + 1,n + 2,...)。表单是基于超级用户创建的表单视图模型动态生成的(类似于https://github.com/Selmanh/angularjs-form-builder)。

因此,在我的用例中,如果我可以从select2的角度判断该值是否无效可能会更容易。

2 个答案:

答案 0 :(得分:2)

在第一个下拉列表中使用ng-change:

<label for="select1" class="control-label">Select1</label>
<select name="select1" ng-model="select1" ng-options="option.select1 as option.select1 for option in options | unique: 'select1' | orderBy: 'select1'" ng-change="select1Changed()">
</select>

<label for="select2" class="control-label">Select2</label>
<select name="select2" ng-model="select2" ng-options="option.select2 as option.select2 for option in options | filter: {select1: select1} | unique: 'select2' | orderBy: 'select2'">
</select>

在您的控制器中:

$scope.select1Changed = function () {
   // logic of known/unknown based on $scope.select1
}

希望这有帮助。

答案 1 :(得分:0)

我最终创建了一个验证指令,用于监视DOM,模型和选项集合的更改。修改集合后,检查值是否为“?”已在视图中选择并考虑未知值。

它足够通用于我的用例,但仍然缺少处理诸如“跟踪”或多个选择以适合所有情况的事情。无论如何,认为这可能对某人有所帮助:

.directive('known', ['$parse', function($parse) {

var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;

return {
    restrict: 'AC',
    require: ['select', '?ngModel'],
    link: function ($scope, $element, $attrs, ctrls) {
        var optionsExp = $attrs.ngOptions,
            modelCtrl = ctrls[1];
        if (match = optionsExp.match(NG_OPTIONS_REGEXP)) {
            var valueName = match[4] || match[6],
                keyName = match[5],
                valueFn = $parse(match[2] ? match[1] : valueName),
                valuesFn = $parse(match[7]);

            $scope.$watchCollection(valuesFn, function() {
                modelCtrl.$setValidity('unknown', !($element.val() == "?" && modelCtrl.$viewValue));
            });

            modelCtrl.$parsers.unshift(function(value) {
                // value set from view can only be a known one
                 modelCtrl.$setValidity('unknown', true);
                 return value;
            });

            modelCtrl.$formatters.unshift(function(value) {
                var values = valuesFn($scope) || [];
                var valid = false;

                for (var i = 0; i < values.length; i++) {
                    var local = {};
                    local[valueName] = values[i];
                    if (value === valueFn(local)) {
                        valid = true;
                        break;
                    }
                }

                modelCtrl.$setValidity('unknown', valid);
                return value;
            });
        }
    }
};
}]);

jsfiddle