DevExtreme Autocomplete 不过滤

DevExtreme Autocomplete does not filter

我正在使用 DevExtreme,但自动完成小部件有问题。

这是我创建自动完成的代码

@(Html.DevExtreme().AutocompleteFor(m => m.CityName)
    .ID("edCity")
    .Placeholder(Html.DisplayNameFor(m => m.CityName).ToString())
    .MinSearchLength(3)
    .SearchTimeout(500)
    .ValueExpr("Name")
    .DataSource(d => d.WebApi().Controller("LNAX").LoadAction("Cities").Key("Name").LoadParams(new { id = 5 }))
)

这是城市class

public class City
{
    public int Id { get; set; }
    public string Name { get; set; }
}

当我开始在退出框中键入内容时。它在下拉列表中显示所有城市。我的期望是根据我输入的内容显示过滤列表。

配置小部件缺少什么?

当用户在编辑框内输入时,您需要使用javascript过滤数据源

@(Html.DevExtreme().AutocompleteFor(m => m.CityName)
    .ID("edCity")
    .Placeholder(Html.DisplayNameFor(m => m.CityName).ToString())
    .MinSearchLength(3)
    .SearchTimeout(500)
    .ValueExpr("Name")
    .DataSource(d => d.WebApi().Controller("LNAX").LoadAction("Cities").Key("Name").LoadParams(new { id = 5 }))
    .OnValueChanged("onCityChange") // add this line
)

然后有一个像这样的 javascript:

function onCityChange(e) {
    if (e.value.length >= 3) {
        var filter = e.value;
        var stateId = 5
        autocompleteData = new DevExpress.data.DataSource(/*a url that returns filtered data based on stateId and filter variables*/);
        autocompleteData.load();
        // set the new data source to your dxAutocomplete widget
        $("#edCity").dxAutocomplete("instance").option("dataSource", autocompleteData);
    }
}

自动完成小部件确实实现了此行为,尽管我在 DevExtreme 支持站点上发现了几篇帖子说您必须改用查找小部件。

关键是自动完成小部件希望您的数据源查找并使用 $filter 和其他参数来 return 正确的过滤列表。您也可以添加自己的参数;见下文。

DevExpress 网站上有一个演示: https://js.devexpress.com/Demos/WidgetsGallery/Demo/Autocomplete/Overview/jQuery/Light/

它是 "Custom Item Template and Data Source Usage" 下的州字段——即使数据集很简单(美国 50 个州的列表),它实际上是在查询远程数据源并 return 过滤列表。这是演示代码(JQuery,其他风格参见演示link):

$("#state").dxAutocomplete({
    dataSource: new DevExpress.data.ODataStore({
        url: "https://js.devexpress.com/Demos/DevAV/odata/States?$select=Sate_ID,State_Long,State_Short",
        key: "Sate_ID",
        keyType: "Int32"
    }),
    placeholder: "Type state name...",
    valueExpr: "State_Long",
    itemTemplate: function(data) {
        return $("<div>" + data.State_Long + 
            " (" + data.State_Short + ")" + "</div>");
    },
    onValueChanged: function(data) {
        state = data.value;
        updateEmployeeInfo();
    }
});   

在状态字段中键入 'ala',注意出现此网络请求(我使用 Chrome 开发人员工具的“网络”选项卡查看请求)。

https://js.devexpress.com/Demos/DevAV/odata/States?$select=Sate_ID,State_Long,State_Short&$top=10&$filter=(substringof(%27ala%27 %2Ctolower(State_Long)))

通过观察 $top$filter 参数,此 return 是仅包含两个状态的预期列表。

您还可以添加自己的参数——我就是这样做的,因为我无法处理参数名称中的 $。只需在数据源的 beforeSend 事件中使用 params

    dataSource: new DevExpress.data.ODataStore({
        url: "https://js.devexpress.com/Demos/DevAV/odata/States?$select=Sate_ID,State_Long,State_Short",
        key: "Sate_ID",
        keyType: "Int32"            
        beforeSend: function (e) {
            console.log(e.params) // Show original params
            e.params.SearchTerm = $("#state").val()
            e.params.Limit = 10
            console.log(e.params) // There's my new params
        }
    })

现在数据源可以使用参数 SearchTermLimit 并忽略其他参数。