Javascript 键入以查询排名较高的结果开头的结果

Javascript 键入以查询排名较高的结果开头的结果,javascript,angularjs,Javascript,Angularjs,我正在使用AngulaJStypeahead指令,如下所示: typeahead="elements.name for elements in someObject.elements | filter:{name:$viewValue} | orderBy:'name' typeahead="elements.name for elements in someObject.elements | filter:{name:$viewValue}:startsWith | orderBy:'nam

我正在使用AngulaJS
typeahead
指令,如下所示:

typeahead="elements.name for elements in someObject.elements | filter:{name:$viewValue} | orderBy:'name'
typeahead="elements.name for elements in someObject.elements | filter:{name:$viewValue}:startsWith | orderBy:'name'
$viewValue
'foo'
时,输出如下所示,并按确切顺序排列:

afoo先走
foo之后是一个酒吧
吧台在foo之前
foo在bar之后
foo酒吧棒极了

我希望查询结果的排名更高,如下所示:

foo在bar之后
foo酒吧棒极了
afoo先走
foo之后是一个酒吧
吧台在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} | orderBy:'name'
typeahead="elements.name for elements in someObject.elements | filter:{name:$viewValue}:startsWith | orderBy:'name'
结果是:

$scope.startsWith = function (state, viewValue) {
   return state.substr(0, viewValue.length).toLowerCase() === viewValue.toLowerCase();
};
foo在bar之后
foo酒吧棒极了


有什么想法吗?

您需要更改orderBy,而不是筛选器。也许在orderBy上执行函数而不是属性可以达到预期的效果

可能是

$scope.typeAheadModel = '';
$scope.orderByPriority = function (element) {
    return element.name.indexOf($scope.typeAheadModel);
}
在HTML中,在您的输入上添加一个
ng模型

ng-model="typeAheadModel" typeahead="element.name for element in someObject.elements | filter:{name:$viewValue} | orderBy:orderByPriority
编辑


这里有一个例子,由于某种原因,当你只键入“f”时,它不能正确地执行,但一旦你键入“fo”,它就会正确地排序。不知道为什么。

我尝试了Ben的方法,这在大多数情况下可能是正确的,但对我来说它不起作用,因为我有递归ng包含,不能使用ng模型

以下是我解决问题的方法(我承认这有点像黑客,但我称之为干净的黑客):

我故意滥用以下筛选器,以便在订购前将viewValue和应用筛选器的属性保存为my
typeaheadService
中的
queryObj
。我还使用它来过滤选择的属性

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
的样子(该服务用于设置和获取所有typeaheads的查询对象):

在my
MainController
中,我将my
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"

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);
}

问题是,函数
orderByPriority
没有将
viewValue
作为参数接收。不幸的是,这不起作用。你知道如何以不同的方式访问查看值吗?嘿,本,谢谢!我尝试了您的方法,但对我来说它不起作用,因为我有递归的ng包含,不能使用ng模型。我找到了一个适合我的解决方案(见我自己的答案)。不管怎样,我想知道你的方法是否有效,这在一般情况下似乎是正确的。你能做一个普朗克吗?做了。很高兴你找到了答案。+1用于概念验证,但奇怪的是,仅仅“f”不能正确排序结果。你也可以执行
orderBy:orderByPriority($viewValue)
并让orderByPriority返回一个进行评分的函数。这正是我想要的。但是很多代码。无论如何谢谢你