有条件地将 "multiple" 属性添加到 ui-select
Conditionally add the "multiple" attribute to ui-select
我正在尝试使用 ng-attr-
指令根据某个 属性 的值将 multiple
属性添加到 ui-select
指令。不幸的是,这对我不起作用。我已经设置了一个 plunker 示例来展示正在发生的事情。
这是你想要达到的效果吗:
<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>
编辑
看完Angular回购中提到的GitHub Issue,我终于明白了。
您需要设置一个具有更高 priority
和 terminal
属性设置为 true 的指令(在我们的指令编译之后跳过所有其他指令的编译)。
然后在 postLink
函数中,我们将编译整个元素本身。但在此之前,我们自己的指令需要被删除(无限循环!)。
Add directives from directive in 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
原始答案(也有效,但代码重复)
我做了以下事情:
- 创建了一个名为
multi-select-checker
的包装指令
- 在该指令中检查
options.Multiple
是真还是假
- Return 每个案例有两个不同的模板 URL。案例 1): return single-select.tpl.html 或案例 2): return mutli-select.tpl.html (其中包括 'multiple' 指令。
指令代码:
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>
模板一:单身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>
模板 2:多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>
如您所见,这两个模板仅在一个指令上有所不同:'multiple'。也许有更好的解决方案。
我什至不明白,为什么 ng-attr-multiple 方法不起作用。
此外,我已经意识到,通过 ng-attr-multiple 方法呈现了两个单独的输入字段。
并且单个 selection 案例似乎被打破了(通过删除 multiple 指令)- 这也在您的初始 Plnkr 中。
工作代码
在此处查看工作 Plnkr:http://plnkr.co/edit/T9e5tcAkcQLsDV3plfEl?p=preview
我正在尝试使用 ng-attr-
指令根据某个 属性 的值将 multiple
属性添加到 ui-select
指令。不幸的是,这对我不起作用。我已经设置了一个 plunker 示例来展示正在发生的事情。
这是你想要达到的效果吗:
<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>
编辑
看完Angular回购中提到的GitHub Issue,我终于明白了。
您需要设置一个具有更高 priority
和 terminal
属性设置为 true 的指令(在我们的指令编译之后跳过所有其他指令的编译)。
然后在 postLink
函数中,我们将编译整个元素本身。但在此之前,我们自己的指令需要被删除(无限循环!)。
Add directives from directive in 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
原始答案(也有效,但代码重复)
我做了以下事情:
- 创建了一个名为
multi-select-checker
的包装指令
- 在该指令中检查
options.Multiple
是真还是假 - Return 每个案例有两个不同的模板 URL。案例 1): return single-select.tpl.html 或案例 2): return mutli-select.tpl.html (其中包括 'multiple' 指令。
指令代码:
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>
模板一:单身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>
模板 2:多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>
如您所见,这两个模板仅在一个指令上有所不同:'multiple'。也许有更好的解决方案。
我什至不明白,为什么 ng-attr-multiple 方法不起作用。
此外,我已经意识到,通过 ng-attr-multiple 方法呈现了两个单独的输入字段。
并且单个 selection 案例似乎被打破了(通过删除 multiple 指令)- 这也在您的初始 Plnkr 中。
工作代码
在此处查看工作 Plnkr:http://plnkr.co/edit/T9e5tcAkcQLsDV3plfEl?p=preview