【问题标题】:select2 remote data: populate using Web API 2 endpointselect2 远程数据:使用 Web API 2 端点填充
【发布时间】:2016-05-18 15:34:54
【问题描述】:

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

出于测试目的,端点只需构建标签集合并将结果作为 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);
    }

我完成了一个单元测试,它也可以使用 Composer 在 Fiddler4 中运行测试返回以下 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 控件中显示为:

标签1[x] 标签2[x]

但是下拉列表是永久显示的。

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

提前致谢。

T

【问题讨论】:

    标签: json ajax endpoint select2 webapi2


    【解决方案1】:

    在花费了几个小时后终于解决了这个问题,主要是因为信息分散,而且新版本的 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 控制器操作。

    【讨论】:

      猜你喜欢
      • 2015-06-27
      • 1970-01-01
      • 2019-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-03
      相关资源
      最近更新 更多