我正在使用AngulaJS typeahead
指令,如下所示:
typeahead="elements.name for elements in someObject.elements | filter:{name:$viewValue} | orderBy:'name'
$viewValue
为'foo'
,输出如下所示,按照确切的顺序:
foo 首先出现 在 foo 之后去了一个吧 bar出现在 foo 之前 酒吧后面有 foo foo 吧很棒
我希望从查询排名更高的结果开始,如下所示:
栏后,foo 来了 foo 吧真棒 foo 首先出现 在 foo 之后去了一个吧 bar出现在 foo
之前但我认为没有办法干净利落地做到这一点。
我也尝试了这个:
$scope.startsWith = function (state, viewValue) {
return state.substr(0, viewValue.length).toLowerCase() === viewValue.toLowerCase();
};
......使用它如下:
typeahead="elements.name for elements in someObject.elements | filter:{name:$viewValue}:startsWith | orderBy:'name'
结果如下:
栏后,foo 来了 foo 吧很棒
有什么想法吗?
答案 0 :(得分:1)
您需要更改orderBy,而不是过滤器。也许在orderBy上执行函数而不是属性会达到预期的效果。
可能类似
$scope.typeAheadModel = '';
$scope.orderByPriority = function (element) {
return element.name.indexOf($scope.typeAheadModel);
}
在您的HTML中,在您的输入中添加ng-model
ng-model="typeAheadModel" typeahead="element.name for element in someObject.elements | filter:{name:$viewValue} | orderBy:orderByPriority
修改强>
这是plunkr,由于某种原因,当你输入“f”时它没有正确地执行它,但是一旦你输入“fo”它就会正确地命令它。不知道为什么。
答案 1 :(得分:1)
我尝试过Ben的方法,这在大多数情况下可能都是正确的,但对我来说它起作用是因为我有递归ng-includes而不能使用ng-model。
以下是我解决问题的方法(我承认,它有点像黑客,但我称之为干净的黑客):
我故意滥用以下过滤器,以便在订购之前保存viewValue以及在我的queryObj
中将过滤器应用于typeaheadService
的属性。我也用它来过滤选择的属性。
app.filter('typeaheadFilter', ['typeaheadService', function (typeaheadService) {
return function (input, queryObj) {
var key = Object.keys(queryObj)[0],
query = queryObj[key];
typeaheadService.setQueryObject(queryObj); // called once, when the viewValue changes
if (!query) {
return input;
}
var result = [];
angular.forEach(input, function (object) {
if (object[key].toLowerCase().indexOf(query.toLowerCase()) !== -1) {
result.push(object);
}
});
return result;
};
}]);
以下是typeaheadService
的外观(此服务用于设置和获取所有类型的查询对象):
app.factory('typeaheadService', [
function () {
var typeaheadQueryObj;
return {
getQueryObject: function () {
return typeaheadQueryObj;
},
setQueryObject: function (queryObj) {
typeaheadQueryObj = queryObj;
}
};
}
]);
在我的MainController
我将smartOrder
功能添加到$scope
:
$scope.smartOrder = function (obj) {
var queryObj = typeaheadService.getQueryObject(),
key = Object.keys(queryObj)[0],
query = queryObj[key];
if (obj[key].toLowerCase().indexOf(query.toLowerCase()) === 0) {
return ('a' + obj[key]);
}
return ('b' + obj[key]);
};
最后,我的typeahead
:
typeahead="element.name for element in elements | typeaheadFilter:{name:$viewValue} | orderBy:smartOrder | limitTo:dropdownMenuLimit"
答案 2 :(得分:0)
Bens方法也不错,它对我很有用,但如果你的列表中包含大写,那就有问题了。
所以你必须转换两个端点:
$scope.typeAheadModel = '';
$scope.orderByPriority = function (element) {
var lower_model = $scope.typeAheadModel.toLowerCase();
var lower_name = element.name.toLowerCase();
return lower_name.indexOf(lower_model);
}