Условно добавьте множественный атрибут в ui-select

Я пытаюсь добавить атрибут multiple в директиву ui-select на основе значения определенного свойства с помощью директивы ng-attr-. К сожалению, это не работает для меня. Я настроил пример плунжера, чтобы продемонстрировать, что происходит.

Пример плункера


person Kassem    schedule 07.08.2015    source источник


Ответы (2)


Редактировать

Я наконец получил его после прочтения упомянутой GitHub Issue в угловое репо.

Вам нужно настроить директиву с более высоким значением priority и атрибутом terminal, установленным в значение true (что пропускает компиляцию всех других директив после компиляции нашей директивы). Затем в функции postLink мы скомпилируем весь элемент целиком. Но перед этим нужно удалить нашу собственную директиву (бесконечный цикл!).

Большие выстрелы в Добавить директивы из директивы в AngularJS

Код директивы

angular.module('app')
  .directive('multiSelectChecker', function ($compile) {
    return {
      restrict: 'A',
      replace: false, 
      terminal: true, //terminal means: compile this directive only
      priority: 50000, //priority means: the higher the priority, the "firster" the directive will be compiled
      compile: function compile(element, attrs) {
        element.removeAttr("multi-select-checker"); //remove the attribute to avoid indefinite loop
        element.removeAttr("data-multi-select-checker"); //also remove the same attribute with data- prefix in case users specify data-multi-select-checker in the html

        return {
          pre: function preLink(scope, iElement, iAttrs, controller) {  },
          post: function postLink(scope, iElement, iAttrs, controller) { 
            if(scope.options.Multiple == true) {
              iElement[0].setAttribute('multiple',''); //set the multiple directive, doing it the JS way, not jqLite way.
            }
            $compile(iElement)(scope);
          }
        };
      }
    };
  });

HTML-код

  <ui-select ng-model="model.choice" multi-select-checker>
    <ui-select-match>{{$item.Title}}</ui-select-match>
    <ui-select-choices repeat="item.Id as item in options.SuggestedValues | filter: { Title: $select.search }">
      <div ng-bind="item.Title | highlight: $select.search"></div>
    </ui-select-choices>
  </ui-select>

Рабочий план:

http://plnkr.co/edit/N11hjOFaEkFUoIyeWqzc?p=preview


Оригинальный ответ (тоже рабочий, но с повторяющимся кодом)

Я сделал следующее:

  1. Создал директиву упаковки под названием multi-select-checker
  2. В этой директиве проверьте, является ли options.Multiple истинным или ложным
  3. Возвращайте два разных URL-адреса шаблона для каждого случая. Случай 1): вернуть single-select.tpl.html или Случай 2): вернуть mutli-select.tpl.html (который включает директиву «несколько».

Код директивы:

app.directive('multiSelectChecker', function() {
return {
    template: '<ng-include src="getTemplateUrl()"/>',
    controller: function($scope) {
      $scope.getTemplateUrl = function() {
        if($scope.options.Multiple == true) {
          console.log("multi-select");
          return "multi-select.tpl.html"
        }
        else {
          console.log("single select");
          return "single-select.tpl.html"
        }
      }
    }
  }
})

Использование в HTML:

<body ng-controller="DemoCtrl">
  <multi-select-checker>
  </multi-select-checker>
</body>

Шаблон 1: одиночный выбор

<ui-select ng-model="model.choice">
    <ui-select-match>{{$item.Title}}</ui-select-match>
    <ui-select-choices repeat="item.Id as item in options.SuggestedValues | filter: { Title: $select.search }">
        <div ng-bind="item.Title | highlight: $select.search"></div>
    </ui-select-choices>
</ui-select>

Шаблон 2: множественный выбор

<ui-select ng-model="model.choice" multiple>
    <ui-select-match>{{$item.Title}}</ui-select-match>
    <ui-select-choices repeat="item.Id as item in options.SuggestedValues | filter: { Title: $select.search }">
        <div ng-bind="item.Title | highlight: $select.search"></div>
    </ui-select-choices>
</ui-select>

Как видите, два шаблона отличаются только одной директивой: «несколько». Может быть, есть лучшие решения.

Я даже не могу понять, почему подход ng-attr-multiple не работает.

Кроме того, я понял, что есть два отдельных поля ввода, отображаемых с помощью подхода ng-attr-multiple.

И случай единственного выбора, кажется, нарушен (путем удаления множественной директивы), который также был в вашем первоначальном Plnkr.

Рабочий код

См. рабочий Plnkr здесь: http://plnkr.co/edit/T9e5tcAkcQLsDV3plfEl?p=preview< /а>

person ilmgb    schedule 07.08.2015
comment
Это правильное решение, но я хотел бы избежать дублирования кода, поэтому я в первую очередь пытался использовать ng-attr. Спасибо, в любом случае :) - person Kassem; 07.08.2015
comment
Вы можете включить дочерние элементы вашего ui-select -›, что уменьшит ваш повторяющийся код. - person ilmgb; 07.08.2015
comment
Еще немного информации о том, чего вы пытаетесь достичь: github.com/angular /angular.js/issues/5524 - person ilmgb; 07.08.2015
comment
Что касается вашего окончательного решения, если кто-то хочет передать переменную из контроллера (без использования $scope), вам нужно создать изолированную область, а затем скомпилировать файл $parent. Благодарю вас! - person Jens Bodal; 01.12.2016
comment
Сам пользовательский интерфейс также использует 2 отдельных шаблона. проверьте код. return theme + (angular.isDefined(tAttrs.multiple) ? '/select-multiple.tpl.html' : '/select.tpl.html'); - person Exlord; 21.02.2018

Это то, чего вы хотите достичь:

<body ng-controller="DemoCtrl">
    This works perfectly well:
    <ui-select ng-model="model.choice" multiple>
        <ui-select-match>{{$item.Title}}</ui-select-match>
        <ui-select-choices repeat="item.Id as item in options.SuggestedValues | filter: { Title: $select.search }">
            <div ng-bind="item.Title | highlight: $select.search"></div>
        </ui-select-choices>
    </ui-select>
    <br />
    <br />
    This does not work:
    <ui-select ng-model="model.choice2" multiple="{{options.Multiple}}">
        <ui-select-match>{{$item.Title}}</ui-select-match>
        <ui-select-choices repeat="item.Id as item in options.SuggestedValues | filter: { Title: $select.search }">
            <div ng-bind="item.Title | highlight: $select.search"></div>
        </ui-select-choices>
    </ui-select>
  </body>
person Tomislav    schedule 07.08.2015
comment
Да, но это не работает. Потому что каким бы ни было значение options.Multiple, всегда будет предполагаться выбор из нескольких вариантов. - person Kassem; 07.08.2015
comment
Да, теперь я вижу. Кажется, что это открытая проблема в angular, пожалуйста, проверьте github.com/angular/angular. js/issues/7714 и ответ Нарретца: привязка к нескольким в настоящее время не поддерживается. Это было запрещено, потому что вызывало проблемы с директивой select. - person Tomislav; 07.08.2015
comment
Да, я использовал директиву ng-attr, чтобы заставить его работать, но это не помогло. Он добавил множественный атрибут, но испортил вложенную директиву ui-select-match: по-видимому, он был скомпилирован до добавления множественного атрибута и, следовательно, он вел себя так же, как и в контексте единственного выбора ui-select. Любые идеи, как обойти это? - person Kassem; 07.08.2015
comment
Извините, чувак, я понятия не имею, как обойти эту проблему. Он не поддерживается фреймворком. - person Tomislav; 07.08.2015