Угловая директива для предварительного выбора значения <select>, если в ngOptions существует только одна опция

0

Я хочу написать директиву, которая будет проверять доступные параметры в области и предварительно выбрать какой-либо вариант, если только один элемент присутствует внутри ngOptions.

На данный момент я написал что-то вроде этого:

<select id="provider" name="provider" class="form-control"
        ng-model="foo.provider"
        ng-options="provider.name for provider in providers track by provider.id"
        select-first-if-only-one="providers"
        required>
    <option value="">- Select -</option>
</select>

и моя директива:

'use strict';

angular.module('app')
    .directive('selectFirstIfOnlyOne', function() {
        return {
            restrict: 'A',
            require: 'select',
            link: function(scope, elem, attrs, ctrl) {
                scope.$watchCollection(attrs.selectFirstIfOnlyOne, function(values) {
                    if (angular.isDefined(values) && values.length === 1) {
                        scope.$evalAsync(function() {
                            ctrl.ngModelCtrl.$setViewValue(values[0]);
                        });
                    }
                });
            }
        };
    });

И это работает. Но я не хочу передавать значения массива непосредственно директиве, а брать их из ngModel или ngOptions.

Я обнаружил, что SelectController не предоставляет методы для получения всех значений из <select>, то же для NgModelController.

  • 0
    Вы можете создать пользовательскую директиву элемента, которая создает элемент select и привязывает к нему параметры
  • 0
    Требовать ngModel в вашей директиве и идти оттуда?
Показать ещё 6 комментариев
Теги:
angularjs-directive

2 ответа

2

Что-то вроде этой скрипки будет работать, если вы не планируете менять ng-параметры без перезагрузки области.

Во-первых, вы не можете получать информацию (насколько мне известно) из ng-options. NgModel еще не имеет значения, что вы пытаетесь установить с этой директивой, если есть только один параметр.

Вы можете сделать это таким образом, разделяя область действия с контроллером:

<div ng-app="app" ng-controller="cont">
    <select id="provider" name="provider" class="form-control"
        ng-model="foo.provider"
        ng-options="provider.name for provider in providers track by provider.id"
        select-first-if-only-one="providers"
            required>
        <option value="">- Select -</option>
    </select>
</div>

angular.module('app', [])
.controller('cont', function($scope) {
    $scope.foo = {}
    $scope.providers = [{name: 'bob', id: 1}]
})
.directive('selectFirstIfOnlyOne', function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs, ctrl) {
            if (scope.providers.length < 2) {
                scope.foo.provider = scope.providers[0];
            }
        }
    };
});

Если вы хотите изолировать область действия, вам необходимо передать информацию через изолированную область var:

html select-first-if-only-one = "providers.length"

angular.module('app', [])
.controller('cont', function($scope) {
    $scope.foo = {}
    $scope.providers = [{name: 'bob', id: 1}]
})
.directive('selectFirstIfOnlyOne', function($parse) {
    return {
        restrict: 'A',
        scope: {options: '=selectFirstIfOnlyOne', model: '=ngModel'},
        link: function(scope, elem, attrs, ctrl) {
            if (scope.options.length < 2) {
                scope.model = scope.options[0];
            }
        }
    };
});

Извините, я делал это немного поспешно и может изменить это еще дальше, если вы все еще не удовлетворены.

  • 0
    Таким образом, директива будет тесно связана с контроллером, и я пытаюсь избежать этого
  • 0
    добавьте область действия в директиву и передайте переменную, я отредактирую пост.
Показать ещё 1 комментарий
1

Разрешено с регулярным выражением:

http://jsfiddle.net/PxdSP/3206/

Код:

angular.module('myApp')
  .directive('selectFirstIfOnlyOne', function () {
    return {
      restrict: 'A',
      require: 'select',
      link: function (scope, elem, attrs, ctrl) {
        var regex = /in (.+?)(?: |$)/; //Here
        var collection = regex.exec(attrs.ngOptions)[1]; // And here

        scope.$watchCollection(collection, function (values) {
          if (angular.isDefined(values) && values.length === 1) {
            scope.$evalAsync(function () {
              ctrl.ngModelCtrl.$setViewValue(values[0]);
              ctrl.ngModelCtrl.$render();
            });
          }
        });
      }
    };
});

Ещё вопросы

Сообщество Overcoder
Наверх
Меню