ghi*_*ing 5 angularjs angularjs-directive angularjs-ng-repeat bootstrap-select
我喜欢Bootstrap-Select并且我目前正在通过另一个用户的指令帮助joaoneto/angular-bootstrap-select它并且它按预期工作,除非我尝试<select>使用$http或在我的情况下用dataService包装器填充我的元素.我似乎得到了一些计时问题,数据在selectpicker显示/刷新后出现,然后我最终得到一个空的Bootstrap-Select列表..虽然使用Firebug,我确实看到了现在隐藏的值列表<select>.如果我然后进入控制台并手动执行$('.selectpicker').selectpicker('refresh')它然后工作.
我通过做一个补丁并添加一个.selectpicker('refresh')内部暂时工作$timeout但是你知道它并不理想,因为我们jQuery直接在ngController中使用...哎哟!
因此,我认为该指令可能缺少观察者,或者至少触发ngModel了更改或更新的内容.
Html示例代码:
<div class="col-sm-5">
<select name="language" class="form-control show-tick"
ng-model="vm.profile.language"
selectpicker data-live-search="true"
ng-options="language.value as language.name for language in vm.languages">
</select>
<!-- also tried with an ng-repeat, which has the same effect -->
</div>
Run Code Online (Sandbox Code Playgroud)
然后在我的Angular Controller中:
// get list of languages from DB
dataService
.getLanguages()
.then(function(data) {
vm.languages = data;
// need a timeout patch to properly refresh the Bootstrap-Select selectpicker
// not so good to use this inside an ngController but it's the only working way I have found
$timeout(function() {
$('.selectpicker, select[selectpicker]').selectpicker('refresh');
}, 1);
});
Run Code Online (Sandbox Code Playgroud)
这是(joaoneto)在GitHub上为Angular-Bootstrap-Select做出的指令
function selectpickerDirective($parse, $timeout) {
return {
restrict: 'A',
priority: 1000,
link: function (scope, element, attrs) {
function refresh(newVal) {
scope.$applyAsync(function () {
if (attrs.ngOptions && /track by/.test(attrs.ngOptions)) element.val(newVal);
element.selectpicker('refresh');
});
}
attrs.$observe('spTheme', function (val) {
$timeout(function () {
element.data('selectpicker').$button.removeClass(function (i, c) {
return (c.match(/(^|\s)?btn-\S+/g) || []).join(' ');
});
element.selectpicker('setStyle', val);
});
});
$timeout(function () {
element.selectpicker($parse(attrs.selectpicker)());
element.selectpicker('refresh');
});
if (attrs.ngModel) {
scope.$watch(attrs.ngModel, refresh, true);
}
if (attrs.ngDisabled) {
scope.$watch(attrs.ngDisabled, refresh, true);
}
scope.$on('$destroy', function () {
$timeout(function () {
element.selectpicker('destroy');
});
});
}
};
}
Run Code Online (Sandbox Code Playgroud)
angular-bootstrap-select指令的一个问题是它只监视ngModel,而不是实际填充select中选项的对象.例如,如果默认情况下vm.profile.language设置为'',并且vm.languages有一个''选项,则选择将不会使用新选项更新,因为ngModel保持不变.我selectModel在select中添加了一个属性,并略微修改了angular-bootstrap-select代码.
<div class="col-sm-5">
<select name="language" class="form-control show-tick"
ng-model="vm.profile.language"
select-model="vm.languages"
selectpicker data-live-search="true"
ng-options="language.value as language.name for language in vm.languages">
</select>
</div>
Run Code Online (Sandbox Code Playgroud)
然后,在angular-bootstrap-select代码中,我添加了
if (attrs.selectModel) {
scope.$watch(attrs.selectModel, refresh, true);
}
Run Code Online (Sandbox Code Playgroud)
现在,vm.languages更新时,选择也将更新.一个更好的方法可能是简单地通过使用来检测应该监视哪个对象ngOptions,但是使用这种方法也允许ngRepeat在select中使用.
编辑:
使用的替代方法selectModel是自动检测要观看的对象ngOptions.
if (attrs.ngOptions && / in /.test(attrs.ngOptions)) {
scope.$watch(attrs.ngOptions.split(' in ')[1], refresh, true);
}
Run Code Online (Sandbox Code Playgroud)
编辑2:
refresh您可能最好element.selectpicker('refresh');再次调用,而不是使用该函数,因为您只想在ngModel更改时实际更新select的值.我遇到了一个更新选项列表的场景,并且选择的值发生了变化,但模型没有改变,因此它与selectpicker不匹配.这解决了我:
if (attrs.ngOptions && / in /.test(attrs.ngOptions)) {
scope.$watch(attrs.ngOptions.split(' in ')[1], function() {
scope.$applyAsync(function () {
element.selectpicker('refresh');
});
}, true);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4871 次 |
| 最近记录: |