[翻译]  Conditionally add the “multiple” attribute to ui-select

[CHINESE]  有条件地将“multiple”属性添加到ui-select


I'm trying to add the multiple attribute to a ui-select directive based on the value of a certain property using the ng-attr- directive. Unfortunately, that's not working for me. I've setup a plunker example to showcase what is happening.

我正在尝试使用ng-attr-指令基于某个属性的值将多属性添加到ui-select指令。不幸的是,那不适合我。我已经设置了一个示例来展示正在发生的事情。

Plunker Example

Plunker示例

2 个解决方案

#1


6  

Edit

I finally got it after reading through the mentioned GitHub Issue in the Angular Repo.

在阅读Angular Repo中提到的GitHub问题后,我终于明白了。

You need to set up a directive with a higher priority and a terminal attribute set to true (which skips the compilation of all other directives, after the compilation of our directive). Then in the postLink function we will compile the whole element itself. But before that our own directive needs to be removed (infinite loop!).

您需要设置一个具有更高优先级的指令和一个设置为true的终端属性(在编译我们的指令后,它会跳过所有其他指令的编译)。然后在postLink函数中,我们将编译整个元素本身。但在此之前我们需要删除自己的指令(无限循环!)。

Big shot outs to Add directives from directive in AngularJS

从AngularJS中的指令添加指令

Directive Code

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 Code

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

Working Plnkr:

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

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


Original answer (also working, but with duplicate code)

I did the following:

我做了以下事情:

  1. Created a wrapping directive called multi-select-checker
  2. 创建了一个名为multi-select-checker的包装指令
  3. In that directive check wether the options.Multiple is true or false
  4. 在该指令中检查options.Multiple是true还是false
  5. Return two different template URLs for each case. Case 1): return single-select.tpl.html or Case 2): return mutli-select.tpl.html (which includes the 'multiple' directive.
  6. 为每个案例返回两个不同的模板URL。情况1):返回single-select.tpl.html或Case 2):return mutli-select.tpl.html(包括'multiple'指令。

Directive code:

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"
        }
      }
    }
  }
})

Usage in HTML:

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

Template 1: single select

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

Template 2: multi-select

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

As you can see the two templates only differ by one single directive: 'multiple'. Maybe there are better solutions.

正如您所看到的,两个模板只有一个指令不同:'multiple'。也许有更好的解决方案。

I even can't understand, why the ng-attr-multiple approach isn't working.

我甚至无法理解,为什么ng-attr-multiple方法不起作用。

In addition I have realized, that there are two seperate input fields being rendered via the ng-attr-multiple approach.

另外我已经意识到,有两个单独的输入字段通过ng-attr-multiple方法呈现。

And the single selection case seems to be broken (by removing the multiple directive) - which was in your intial Plnkr as well.

单一选择案例似乎被打破(通过删除多指令) - 这也是你的初始Plnkr。

Working Code

See the working Plnkr here: http://plnkr.co/edit/T9e5tcAkcQLsDV3plfEl?p=preview

在这里查看工作的Plnkr:http://plnkr.co/edit/T9e5tcAkcQLsDV3plfEl?p = preview

#2


3  

Is this what you want to achieve:

这是你想要实现的目标:

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

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2018 ITdaan.com 粤ICP备14056181号