Angular Material 自动完成 - 在 Select 上搜索
Angular Material Autocomplete - Searches on Select
我在 Angular Material 中创建了这个很酷的小控件,欢迎任何人使用(参见 fiddle)。它基本上是一个 Angular Material 的自动完成字段,在您键入时利用 Google 的地理定位服务。由于没有延迟指令,我添加了特殊代码以仅在用户在 700 毫秒后停止输入时进行搜索。
我的问题是 - 为什么 MD-Autocomplete 在选择项目后立即触发查询事件?
这里是HTML:
<md-autocomplete flex style="width: 50%; margin: auto; padding-top: 10em"
md-no-cache="false"
md-selected-item="ctrl.orig_loc"
md-search-text="ctrl.orig_loc_query"
md-items="item in querySearch(ctrl.orig_loc_query)"
md-selected-item-change="selectedItem(ctrl.orig_loc)"
md-item-text="ctrl.orig_loc.formatted_address"
md-floating-label="Type address or location name">
<span md-highlight-text="">{{item.formatted_address}}</span>
</md-autocomplete>
这里是 JS querySearch 函数:
// this is called every time a user types a character AND when item is selected... for some odd reason
$scope.querySearch = function(query) {
var deferred = $.Deferred();
// clear old request if something typed within 700ms
if (locQuery) {
clearTimeout(locQuery);
}
// run the query in 700ms. it will be cleared if the user types within 700ms
locQuery = setTimeout(function() {
// call google's geocoder
geocoder.geocode({
'address': query
}, deferred.resolve);
}, 700);
return deferred.promise().then(function(response) {
return response;
});
};
这是 fiddle:
https://jsfiddle.net/NeoSHNIK/jgpgv4Ls/3/
同样,问题是 - 在您做出选择后,它会进行另一次搜索...为什么?
我有点明白了。它的发生是因为字段的变量 "searchText" 在被我的格式化程序“{{item.formatted_address}}”格式化之前更改了两次。 angular-material 库中的 $scope.$watch 正在监视此字段。所以每次它改变时 - 他们调用 handleSearchText() 来进行搜索。因此,他们实际上应该添加一个 "delay" 概念来解决我的问题以及远程搜索的问题(不想搜索用户键入的每个字符)。为自动完成控件添加延迟会很好。但现在我只是修改了 angular-material 库,它完成了工作:
function configureWatchers () {
var wait = 700; //MY HACK
$attrs.$observe('disabled', function (value) { ctrl.isDisabled = $mdUtil.parseAttributeBoolean(value, false); });
$attrs.$observe('required', function (value) { ctrl.isRequired = $mdUtil.parseAttributeBoolean(value, false); });
$attrs.$observe('readonly', function (value) { ctrl.isReadonly = $mdUtil.parseAttributeBoolean(value, false); });
$scope.$watch('searchText', wait ? $mdUtil.debounce(handleSearchText, wait) : handleSearchText);
$scope.$watch('selectedItem', selectedItemChange);
angular.element($window).on('resize', positionDropdown);
$scope.$on('$destroy', cleanup);
}
我在 Angular Material 中创建了这个很酷的小控件,欢迎任何人使用(参见 fiddle)。它基本上是一个 Angular Material 的自动完成字段,在您键入时利用 Google 的地理定位服务。由于没有延迟指令,我添加了特殊代码以仅在用户在 700 毫秒后停止输入时进行搜索。
我的问题是 - 为什么 MD-Autocomplete 在选择项目后立即触发查询事件?
这里是HTML:
<md-autocomplete flex style="width: 50%; margin: auto; padding-top: 10em"
md-no-cache="false"
md-selected-item="ctrl.orig_loc"
md-search-text="ctrl.orig_loc_query"
md-items="item in querySearch(ctrl.orig_loc_query)"
md-selected-item-change="selectedItem(ctrl.orig_loc)"
md-item-text="ctrl.orig_loc.formatted_address"
md-floating-label="Type address or location name">
<span md-highlight-text="">{{item.formatted_address}}</span>
</md-autocomplete>
这里是 JS querySearch 函数:
// this is called every time a user types a character AND when item is selected... for some odd reason
$scope.querySearch = function(query) {
var deferred = $.Deferred();
// clear old request if something typed within 700ms
if (locQuery) {
clearTimeout(locQuery);
}
// run the query in 700ms. it will be cleared if the user types within 700ms
locQuery = setTimeout(function() {
// call google's geocoder
geocoder.geocode({
'address': query
}, deferred.resolve);
}, 700);
return deferred.promise().then(function(response) {
return response;
});
};
这是 fiddle: https://jsfiddle.net/NeoSHNIK/jgpgv4Ls/3/
同样,问题是 - 在您做出选择后,它会进行另一次搜索...为什么?
我有点明白了。它的发生是因为字段的变量 "searchText" 在被我的格式化程序“{{item.formatted_address}}”格式化之前更改了两次。 angular-material 库中的 $scope.$watch 正在监视此字段。所以每次它改变时 - 他们调用 handleSearchText() 来进行搜索。因此,他们实际上应该添加一个 "delay" 概念来解决我的问题以及远程搜索的问题(不想搜索用户键入的每个字符)。为自动完成控件添加延迟会很好。但现在我只是修改了 angular-material 库,它完成了工作:
function configureWatchers () {
var wait = 700; //MY HACK
$attrs.$observe('disabled', function (value) { ctrl.isDisabled = $mdUtil.parseAttributeBoolean(value, false); });
$attrs.$observe('required', function (value) { ctrl.isRequired = $mdUtil.parseAttributeBoolean(value, false); });
$attrs.$observe('readonly', function (value) { ctrl.isReadonly = $mdUtil.parseAttributeBoolean(value, false); });
$scope.$watch('searchText', wait ? $mdUtil.debounce(handleSearchText, wait) : handleSearchText);
$scope.$watch('selectedItem', selectedItemChange);
angular.element($window).on('resize', positionDropdown);
$scope.$on('$destroy', cleanup);
}