基于AngularJS 1.3.20与Bootstrap改造可搜索下拉选择框指令
Got it! Since you're working with Angular 1.3.20 and angular-bootstrap ~0.12.1, here's a modified version of your mySelector directive that transforms the plain dropdown into a searchable select component—all while preserving every existing feature you had:
.directive('mySelector', function() { return { template: ` <div class="my-selector-container"> <input type="text" class="form-control" ng-model="selectedItem" typeahead="e as (e.number + ' - ' + e.name) for e in filteredItems | filter:$viewValue" typeahead-on-select="onItemSelect($item)" ng-required="{{objectRequired}}" ng-disabled="allowModify == false" placeholder="{{$parent.labelItem}}"> <!-- Hidden input maintains backward compatibility with original inputIdItem binding --> <input type="hidden" ng-model="inputIdItem"> </div> `, restrict: 'E', scope: { inputIdItem: '=', inputIdOther: '=', afterList: '=', objectRequired: '=', allowModify: '=', listFilter: '=' }, controller: function($scope, $filter) { // Sync filtered items when parent data or listFilter changes $scope.$watch('$parent.getItems', function(items) { if (items) { $scope.filteredItems = $scope.listFilter ? $filter('filter')(items, $scope.listFilter) : items; } }, true); $scope.$watch('listFilter', function(newFilter) { if ($scope.$parent.getItems && newFilter) { $scope.filteredItems = $filter('filter')($scope.$parent.getItems, newFilter); } }, true); // Initialize selected item based on inputIdItem $scope.$watch('inputIdItem', function(newId) { if (newId && $scope.filteredItems) { $scope.selectedItem = $filter('filter')($scope.filteredItems, {id: newId})[0]; } else if (newId === '') { $scope.selectedItem = null; } }); // Handle item selection logic $scope.onItemSelect = function(item) { $scope.inputIdItem = item ? item.id : ''; // Trigger original reload logic if ($scope.$parent.reloadOtherSelector) { $scope.$parent.reloadOtherSelector($scope.inputIdItem, $scope.afterList); } // Clear associated inputIdOther as before if (!angular.isUndefined($scope.inputIdOther) && item) { $scope.inputIdOther = null; } }; } }; })
Key Changes Explained
- Template Overhaul: Replaced the
<select>with an input using angular-bootstrap'stypeaheaddirective (supported in 0.12.1). A hidden input keeps the originalinputIdItembinding intact, so your existing parent scope logic doesn't need any changes. - Built-in Search: The
typeaheadusesfilter:$viewValueto automatically filter options as the user types—no extra code needed for search logic. - Preserved Original Features:
- Kept
ng-requiredandng-disabledcontrols - Retained the
reloadOtherSelectortrigger on selection - Maintained the behavior of clearing
inputIdOtherwhen a new item is selected - Still supports your custom
listFilterfor pre-filtering options
- Kept
- Data Sync: Added watches to ensure the selected item and
inputIdItemstay in sync, even when the parent data source or filter changes.
Optional CSS Tweaks
Make the component look polished with a little styling:
.my-selector-container { position: relative; } /* Limit dropdown height and add scroll for long lists */ .dropdown-menu { max-height: 200px; overflow-y: auto; }
Important Notes
- Module Dependency: Make sure your main app module depends on
ui.bootstrap.typeahead(the correct module name for 0.12.1):angular.module('yourApp', ['ui.bootstrap.typeahead']); - Parent Data Source: The directive still relies on
$parent.getItemsas the source of options—ensure this exists in the parent scope as an array. - Custom Search: If you need more control over search matching, you can replace
filter:$viewValuewith a custom Angular filter.
内容的提问来源于stack exchange,提问作者Gabriel S.
相关产品推荐
相关产品推荐

