如何在DataSourceRequest

时间:2017-09-14 13:28:28

标签: javascript kendo-ui

我正在尝试将工具栏的“搜索文本框”值发送到WEB API操作。我搜索了各种在线解决方案。但是,似乎都没有效果。

在客户端,我在'搜索文本框'上有一个'KeyUp'事件。完成后,我需要将值附加到READ。

我已经尝试了以下(客户端):

// This Fails
var value = dictionary.elements.txtDeviceSearch.val();
var url = "api/devicedataitem/search?text='" + value + "'";

dictionary.instances.gridDevices.dataSource.options.transport.read.url = url;
dictionary.instances.gridDevices.dataSource.read();

// This Fails
dictionary.instances.gridDevices.dataSource.options.transport.read.data = { text: value };
dictionary.instances.gridDevices.dataSource.read();

// This Fails
dictionary.instances.gridDevices.dataSource.read({ text: 'Work Dammit' });

enter image description here

初步调用的工作原理如下:
这是按预期工作的......

@(Html.Kendo().Grid<DeviceDataItem>()
    .Name("gridDevices")
    .DataSource(dataSource => dataSource
        .WebApi()
        .Model(model =>
        {
            model.Id(m => m.DeviceId);
            model.Field(m => m.DeviceName);
            model.Field(m => m.CommunicationTechnicianId);
            model.Field(m => m.CommunicationTechnicianFullName);
            model.Field(m => m.MeasurementTechnicianId);
            model.Field(m => m.MeasurementTechnicianFullName);
        })
        .Read(read => read.Url("api/devicedataitem/search?text=''").Type(HttpVerbs.Post))
    )
    .ToolBar(toolbar =>
    {
        toolbar.Template(@<text>
            <div class="input-group pull-right" role="toolbar">
                <span class="input-group-addon">
                    <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
                </span>
                <input type="text" class="form-control" id='txtDeviceSearch' placeholder="Search for..." />
            </div>
        </text>);
    })
    .Deferred(true))

enter image description here

3 个答案:

答案 0 :(得分:2)

现在我们到了某个地方,这个问题比另一个好。在我放弃之前,我要说的是,在JavaScript小部件中有一个名为parameterMap的参数,您可以在其中操作将在请求中发送到API的数据。正如文档中所述,您可以尝试:

parameterMap: function (data, type) {
    return kendo.stringify($.extend({ "text": $("#txtDeviceText").text() }, data));
}

但是我不知道如何将它添加到剃须刀助手中,因为他们的文档太糟糕了,我无法测试它。所以你可以尝试:

  1. 在初始化中添加参数(我不确定是否有效):

    DataSource(dataSource => dataSource.ParameterMap("jsFunctionNameHere")
    

    或类似的东西;

  2. 初始化后在网格中设置:

    $("#grid").data("kendoGrid").dataSource.transport.parameterMap = function() {
        return { text: $("#txtDeviceText").text() };
    };
    

    Demo

  3. 我打赌第二个选项,它应该有用。

答案 1 :(得分:1)

尝试一下:

dictionary.instances.gridDevices.dataSource.type = "aspnetmvc-ajax";

我们在应用程序中执行相同的操作,除了DataSourceRequest对象之外,还将参数发送到控制器操作。删除该类型设置后,我会对使用空值接收的参数执行相同的操作。

使用与此类似的js定义数据源:

this.results = new kendo.data.DataSource({
    type: "aspnetmvc-ajax",
    transport: {
        read: {
            url: "Controller/Search",
            data: function () {
                return {
                    value: "abc"
                };
            }
       }
    }
});

当触发read()时,它会按照以下方式触发控制器操作:

public JsonResult Search([DataSourceRequest] DataSourceRequest request, string value)

所以没有任何异常,但删除了该类型,没有收到该值。请注意,这是一个System.Web.MVC.Controller,而不是System.Web.Http.ApiController,虽然我看不出这会产生什么影响。也可能是数据源类型只能在设置时有效地设置(因此它会进入定义,而不是像我最初建议的那样改变),但这只是另一种猜测。我感觉到你的痛苦 - 这种事情应该起作用。

答案 2 :(得分:1)

好吧,我终于想到了这个&amp;这个很难。这个特殊的答案有很多方面:

  • 使用GET
  • 因此,GET需要使用“模型粘合剂属性”
  • 现在包含一个小的POST示例......

GET - WEB API:
这是有效的,因为“模型绑定器属性”抓取了REQUEST对象&amp;为你保湿。没有它,REQUEST将始终 null

// GET: /api/DeviceDataItem/Search
[HttpGet]
public DataSourceResult Search([ModelBinder(typeof(WebApiDataSourceRequestModelBinder))] DataSourceRequest request, string search)
{
    var application = (MyApplication)Application;
    var provider = (DeviceDataItemProvider)application.DeviceDataItemProvider;

    IQueryable<DeviceDataItem> query = provider.Query();

    // No 'Where' needed
    if (string.IsNullOrWhiteSpace(search))
        return query.ToDataSourceResult(request);

    // Where
    ...your WHERE logic goes here...

    return query.ToDataSourceResult(request);
}

GET - MVC。阅读:
注意我指的是通过窗口公开提供的自定义Page Controller对象。

.Read(read => read.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "DeviceDataItem", action="Search"}))
                          .Type(HttpVerbs.Get)
                          .Data("window.pageController.on.read.gridDevices"))

GET - JavaScript:
我碰巧将我的对象缓存在页面控制器中 - 你必须引用你的对象(不过它们是构建的)。

this.on = {
    read: {
        gridDevices: function () {
            return {
                search: dictionary.elements.txtDeviceSearch.val()
            }
        }
    },
    search: {
        gridDevices: function (e) {

            lazyInitGridDevices();

            // Clear
            dictionary.instances.gridDevices.dataSource.data([]);
            dictionary.instances.gridDevices.refresh();

            // Read
            dictionary.instances.gridDevices.dataSource.read();
        }
    }
};

POST:
根据Telerik的说法,相同的方法用于将参数传递给POST请求。但是,使用Web API时,无法将第二个参数添加到方法签名中。解决此问题的一种可能方法是使用JObject从请求中获取所有数据,然后使用此数据构造新的模型对象。

例如:

public HttpResponseMessage Post(JObject jsonData)
{
    ProductViewModel product = new ProductViewModel() {
        ProductName = (string)jsonData["ProductName"],
        UnitPrice = (decimal)jsonData["ProductID"],
        UnitsInStock = (int)jsonData["ProductName"],
        Discontinued = (bool)jsonData["ProductID"]
    };
    string searchTerm = (string)jsonData["search"];

    .............
}