select2远程数据:使用Web API 2端点填充

时间:2016-05-18 15:34:54

标签: json ajax endpoint select2 webapi2

根据标题我在HTML5页面上使用最新的select2选择框并使用他们的示例我正在调用我创建的Web API 2端点。

出于测试目的,端点只是构建一个Tags集合,并将结果作为HttpResponseMessage返回。以下是一些可视化的代码:

标签实体

public class TagData
{
    public string Id { get; set; }
    public string Text { get; set; }
}

模特:

public class TagsModel
{
    public IEnumerable<TagData> Tags { get; set; }
}

Web API 2项目中的控制器操作:

    public IHttpActionResult Get()
    {
        var tags = new TagsModel()
        {
            Tags = new List<TagData>
            {
                new TagData()
                {
                    Id = "1",
                    Text = "Tag1"
                },
                new TagData()
                {
                    Id = "2",
                    Text = "Tag2"
                }
            }
        };
        return Ok(tags);
    }

我敲了一个单元测试,所有工作都在Fiddler4中运行测试,使用composer返回以下JSON响应:

{"Tags":[{"Id":"1","Text":"Tag1"},{"Id":"2","Text":"Tag2"},{"Id":"3","Text":"Tag3"}}]}

在HTML5页面中,我删除了标准的select2 html元素:

    <select class='s2-search-box form-control' multiple='multiple'></select>

这里的想法是将select2控件绑定到远程数据,然后使用标记功能允许用户查找标记,选择它并重复以便使用此ajax调用完成:

    $(document).ready(function () {

        $(".s2-search-box").select2({
            ajax: {
                url: "http://localhost:54850/api/s2demo",
                dataType: 'json',
                delay: 250,
                data: function (params) {
                    return {
                        q: params.term, // search term
                        page: params.page
                    };
                },
                processResults: function (data, page) {
                    // parse the results into the format expected by Select2.
                    // since we are using custom formatting functions we do not need to
                    // alter the remote JSON data
                    return {
                        results: data.Tags
                    };
                },
                cache: true
            }
        });
    });

到目前为止这么好,我的单元测试工作,当我使用Firebug检查ajax调用时,我可以看到以正确的格式返回的数据,我能够显示data.Tags集合所以我知道数据在那里但实际的select2下拉列表会显示“未定义”项目列表,并不会实际显示我想要的数据或允许我从这些选项中创建标记。

作为附注,我也尝试了这个:

    $(".s2-search-box").select2({
        ajax: {
            url: "http://localhost:54850/api/s2demo",
            dataType: "json",
            type: "GET",
            data: function (params) {

                var queryParameters = {
                    term: params.term
                }
                return queryParameters;
            },
            processResults: function (data) {
                return {
                    results: $.map(data, function (item) {
                        return {
                            text: item.Text,
                            id: item.Id
                        }
                    }),
                    pagination: {
                        more: data.more
                    }
                };
            }
        }
    });

这适用于我可以创建标记,使它们在select2控件中显示为:

tag1 [x] tag2 [x]

但下拉列表会永久显示。

我使用的是select2库的最新4.0.2版本。

提前致谢。

T

1 个答案:

答案 0 :(得分:3)

在经过一段时间的烧毁之后终于解决了这个问题,主要是因为信息分散,而且由于新版本的select2现在没有得到广泛使用。

所以我必须做一些更改,首先是对控制器允许我发出GET和POST请求(有更好的方法来做到这一点,但为了原型设计的目的):

    [AcceptVerbs("GET","POST")]
    public IHttpActionResult TagLookup([FromBody]string value)
    {
        var tags = TagsModel;

        var results = new TagsModel();
        var tagsList = new List<TagData>();
        var i = 0;

        foreach (var m in tags.Tags)
        {
            i++;
            if (m.Text.Contains(value))
            {
                tagsList.Add(new TagData()
                {
                    Id = i.ToString(),
                    Text = m.Text
                });
            }
        }

        results.Tags = tagsList;

        return Ok(results);
    }

代码块很简单,我返回一个包含标签集合的模型(TagaData实体)但不同的是动作上的装饰器,AcceptVerbs属性接受来自任何客户端的GET和POST请求。

此外,我添加了[FromBody]参数属性,该属性强制Web API从请求正文中读取一个简单类型(对于您将使用FromUri的复杂类型)。

然后我在HTML页面中修改了Ajax调用,如下所示:

    $(document).ready(function () {

        $(".s2-search-box").select2({
            ajax: {
                url: "http://localhost:54850/api/s2demo",
                contentType: "application/x-www-form-urlencoded; charset=UTF-8",
                type: 'POST',
                dataType: 'json',
                delay: 250,
                data: function(params) {
                    return '=' + params.term; // search term
                },
                processResults: function(data) {
                    return {
                        results: $.map(data.Tags, function(item) {
                            return {
                                text: item.Text,
                                id: item.Id
                            }
                        })
                    };
                },
                cache: true
            }
        });
    });

因此,这里需要注意的重要事项是将参数传递给正在发送的数据有效负载的函数,但是Web API 2的问题是我必须使用的'='符号:

return '=' + params.term; 

这是必需的,因此Web API了解如何处理参数,否则会被忽略。

'processResults:'部分标记Tags数组并将数据绑定到select2控件,为我提供一个填充的下拉列表(如果返回的任何数据与传入的术语匹配)。

现在我也可以选择一个标签,它会在select2中显示为输入框中的标签,我这样做是为了确保select2 html控件中包含多个属性:

<select class="s2-search-box form-control" multiple="multiple"></select>

这对我来说很有希望能为其他任何人摸不着头脑提供一些启示。在下一部分中,获取select2框中的标记并将其发送到另一个Web API控制器操作。