Javascript 将Breeze与支持服务器端分页的OData服务一起使用

Javascript 将Breeze与支持服务器端分页的OData服务一起使用,javascript,odata,breeze,Javascript,Odata,Breeze,Breeze查询返回一个对象,该对象包含结果、已触发查询的信息、内联计数和XHR。但就我所见,当OData服务配置为在多个页面中返回数据时,不会捕获nextLink。有没有一种方法可以使用上一个请求的结果向nextLink发送请求,而不是使用skip and take创建查询?我很确定答案是,它目前不支持这种方法。也许@wardbell可以插话。虽然Breeze被设计为将OData作为底层服务类型“很好地”工作,但它并不意味着与OData规范及其所有功能完全一致。它实际上只是利用OData作为基

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

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


但是服务器端分页在OData中是很重要的,所以希望他们能在某个时候增加对这方面的支持。

如果您考虑在MSDN上支持OData查询的话

向下滚动到服务器驱动页面主题,您将看到,如果使用[Queryable(PageSize=10)]属性修饰控制器中的Get,则返回的JSON包含一个

[Queryable(PageSize=10)]
public IQueryable<Product> Get() 
{
    return products.AsQueryable();
}
您应该能够使用它来获取下一页。在页面上的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中检查返回的数据,以确保正确解析出skip值。我的代码很容易出错,因为我没有在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);

正如我所说,我在回复中编写了这段代码,但还没有对其进行测试,但它应该能让您确定最适合您的应用程序。

感谢您的努力。我刚开始玩Breeze,想知道是否有内置的支持来处理服务器端分页。正如Brian Noyes所说,没有内置的支持。因此,我们必须手动处理这些事情。我理解你在这里尝试的方法,我一定会尝试一下。我想知道Breeze团队是否计划在将来的版本中加入此功能。
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);