2

Breeze 查询返回一个对象,其中包含结果、所触发查询的信息、内联计数和 XHR。但据我所见,当 OData 服务配置为在多个页面中返回数据时,不会捕获 nextLink。有没有办法使用先前请求的结果向 nextLink 发送请求,而不是使用 skip and take 创建查询?

4

2 回答 2

2

我很确定答案是它目前不支持。也许@wardbell 可以加入。虽然 Breeze 旨在与 OData 作为底层服务类型“良好”地工作,但它并不意味着完全符合 OData 规范及其所有功能。它实际上只是利用 OData 作为基于服务的 CRUD 模式的标准化协议,它可以在其之上运行。

但是服务器端分页在 OData 中很重要,所以希望他们可以在某个时候添加对它的支持。

于 2013-10-27T10:31:59.033 回答
0

如果您查看 MSDN 上的 Supporting OData Query

http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options

向下滚动到 Server Driven Pages 主题,您将看到,如果您在控制器中使用 [Queryable(PageSize=10)] 属性装饰 Get,则返回的 JSON 包含一个

[Queryable(PageSize=10)]
public IQueryable<Product> Get() 
{
    return products.AsQueryable();
}

返回

{
  "odata.metadata":"http://localhost/$metadata#Products",
  "value":[
    { "ID":1,"Name":"Hat","Price":"15","Category":"Apparel" },
    { "ID":2,"Name":"Socks","Price":"5","Category":"Apparel" },
    // Others not shown
  ],
  "odata.nextLink":"http://localhost/Products?$skip=10"
}

您应该可以使用它来获取下一页。在页面上的 dataservice.js 中,调用返回的结果是 JSON。

您应该能够在查询参数中使用 .skip。

var getProducts = function (callback) {
    // get pageNumber from the viewModel
    var pageNumber = window.app.vm.Products.pageNumber();
    // ditto pageSize
    var pageSize = window.app.vm.Products.pageSize ();
    // set up your query
    var query4 = EntityQuery.from("Products")
        .orderBy("ProductName")
        .skip(pageNumber * pageSize)
        .take(pageSize);
    }
    // execute the query returning the promise from breeze and q
    // when the promise resolves, get the data and act on it
    return manager.executeQuery(query4)
        .then(function (data) {
             // set your viewModel ko.observableArray to the returned items
             window.app.vm.products.products(data.odata.value);
             // set your viewModel ko.observable to the pageNumber                                       window.app.vm.products.pageNumber(data.odata.nextlink.substring(indexOf("skip=") + 1) / pageSize);                 
        })
        .fail(queryFailed);

我只是在脑海中写下了这段代码,因此您需要在浏览器 F12 和 dataservice.js 中检查返回的数据,以确保您正确解析了跳过值。我的代码很容易出错,因为我没有在我的 SPA 中分页数据。我只是建议将其作为一种方法。

在我的 viewModel.activate() 方法中,我会做这样的事情。

app.vm.products = (function ($, ko, dataservice, router) {
    var products = ko.observableArray();
    var pageNumber = ko.observable(1); 
    var pageSize = ko.observable(10);      
    var initialized = false;               // private

    var activate = function (routeData, callback) {
        if (initialized) {
            return;
        }
        initialized = true;
        dataservice.getProducts();
        // I do not think you will have an async timing issue here because the 
        //  get of the pageNumber happens before the ajax call
        //  which would be the major source of latency.
        // If you run into a problem with it updating too quickly you can start with 
        //  page number 0, or put the increment in a callback from the dataservice
        //  method.
        pageNumber(pageNumber() + pageSize);


    },
    ...

    return {
        activate: activate,            
        products: products 
    };
})($, ko, app.dataservice, app.router);

就像我说的那样,我在响应中编写了这段代码并没有对其进行测试,但它应该足以让您确定最适合您的应用程序。

于 2013-10-28T17:37:41.703 回答