angular-ui-select 的TAGGING功能
angular-ui-select 是angular-ui旗下的一款下拉选择的控件,可以实现单选或者多选,功能强大,控制简单。
github: https://github.com/angular-ui/ui-select
Examples: http://angular-ui.github.io/ui-select/
WIKI: https://github.com/angular-ui/ui-select/wiki
ui-select指令的相关配置文档说明: https://github.com/angular-ui/ui-select/wiki/ui-select
tagging功能
tagggin功能主要实现用户在选择的时候发现没有自己想要的选项,这时想要通过自己的输入自动新建一个选项。
简单的配置如下:
main.html
<ui-select ng-model="vm.result" theme="bootstrap" on-select="vm.onSelect($select)" tagging="vm.newTag" taggging-label="('new')" tagging-tokens=",|ENTER|\">
<ui-select-match placeholder="Select or search a person in the list...">{{$select.selected['name']}}
</ui-select-match>
<ui-select-choices repeat="item in vm.field.model | filter: $select.search">
<div ng-bind-html="item.name | highlight: $select.search"></div>
<small ng-bind-html="item.email | highlight: $select.search"></small>
</ui-select-choices>
</ui-select>
index.js
;(function() {
angular.module("up.uform")
.directive('mayaUiSelectSingleTagging', function($parse) {
return {
restrict: 'EA',
controller: function($scope) {
var vm = this;
vm.newTag = function(newTag){
...
};
vm.onSelect = function($select){
.....
}
},
controllerAs: 'vm',
templateUrl: 'main.html',
link: function(scope, elem, attr) {
}
}
})
})();
如上面所示,基本的配置基本完成,但实际上在使用的时候却有问题:
使用ENTER触发tagging时无效
在本例中使用的是, \ ENTER
按键都可以触发tagging功能,但是,在实际使用的时候发现,,
和\
都可以成功的触发tagging功能,唯独ENTER键没法触发
。
在google时发现网上也有不少人遇到了类似的问题,不过都没有完整的解决方案:这似乎是这个组件本身的问题。主要原因是在按下enter
的时候,会将$select.selected
清空,而tagging相关的方法在之后执行,在执行的时候会判断$select.selected
是否为空,为空则不做处理。
解决
通过手动调试的方式,将功能定位到了代码的 _handleDropDownSelection
函数,该函数是在进行选择处理的时候,对一些按键的处理,该函数中关于ENTER
的处理定义如下
case KEY.ENTER:
if(ctrl.open && (ctrl.tagging.isActivated || ctrl.activeIndex >= 0)){
ctrl.select(ctrl.items[ctrl.activeIndex], ctrl.skipFocusser); // Make sure at least one dropdown item is highlighted before adding if not in tagging mode
} else {
ctrl.activate(false, true); //In case its the search input in 'multiple' mode
}
break;
注意到,其中的ctrl.select
方法的执行条件是
- 下拉菜单打开
- tagging功能打开或者已经有选择
问题就出现在条件2
当按下ENTER
键的时候,当没有对应的选项时,此时ctrl.activeIndex
其实是小于0的。
因此依然会触发ctrl.select
方法。
这时这个方法发现并没有选择什么,就会将$select.selected
置空。
因此解决方案很简单,将源码修改一下,加上一句就行。
case KEY.ENTER:
if(ctrl.open && (ctrl.tagging.isActivated || ctrl.activeIndex >= 0)){
if(!ctrl.tagging.isActivated) ctrl.select(ctrl.items[ctrl.activeIndex], ctrl.skipFocusser); // Make sure at least one dropdown item is highlighted before adding if not in tagging mode
} else {
ctrl.activate(false, true); //In case its the search input in 'multiple' mode
}
break;