2013-10-25 67 views
2

Breeze查詢返回包含結果的對象,查詢觸發信息,內聯計數和XHR。但就我所見,當OData服務配置爲以多頁返回數據時,不會捕獲nextLink。有沒有一種方法可以使用前一個請求的結果向nextLink發送請求,而不是使用skip和take創建查詢?使用Breeze啓用服務器端分頁OData服務

回答

2

我很確定答案是它不支持在當前時間。也許@wardbell可以嵌入。雖然Breeze被設計爲可以與OData一起作爲基礎服務類型「很好地」工作,但它並不意味着完全與OData規範及其所有功能保持一致。它實際上只是將OData作爲基於服務的CRUD模式的標準化協議,它可以在其上運行。

但服務器端分頁在OData中很重要,所以希望他們能夠在某些時候增加對此的支持。

0

如果你看一下在MSDN支持的OData查詢

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

向下滾動到服務器驅動頁面的主題,你會看到,如果你裝飾你得到了[可查詢控制器(每頁= 10)]屬性,返回的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); 

就像我說的,我在寫響應此代碼,並沒有測試它,但它應該給你足夠的,以確定最適合您的應用程序。

+1

感謝您的所有努力。我剛開始玩Breeze,想知道內置的是否支持處理服務器端分頁。正如Brian Noyes所說,沒有內置的支持。所以我們必須手動處理這些事情。我瞭解你嘗試在這裏放置的方法,我一定會試一試。我想知道Breeze團隊是否計劃在未來的版本中包含此功能。 –