2016-02-04 147 views
10

我建立了一個管理頁面角流星查詢掛起瀏覽器

發表所有從一個集合中記載:「帖子」,並已採取對前端所有記錄訂閱

$meteor.subscribe('posts'); 

在控制器中,如果我選擇的所有記錄的遊標minimongo正常工作,如:

$scope.posts = $meteor.collection(Posts); 

但我想顯示分頁,所以,我想在一個有時間限制的記錄例如:

$scope.posts = $meteor.collection(function(){ 

     return Posts.find(

      {}, 
      { 
       sort: {'cDate.timestamp': -1}, 
       limit: 10 
      } 
     ); 
    }); 

它在minimongo中查詢。瀏覽器掛起。

帖子」 集合只包含500條記錄。當我有200條記錄時,它工作正常。

誰能給我一個想法,什麼是錯我的代碼和概念?

編輯:

好吧!它工作得很好,當我從評論的查詢$排序一行:

$scope.posts = $meteor.collection(function(){ 

      return Posts.find(

       {}, 
       { 
        //sort: {'cDate.timestamp': -1}, 
        limit: 10 
       } 
      ); 
     }); 

但我需要對記錄進行排序。那麼我現在該做什麼?

編輯:

也嘗試添加索引排序屬性是這樣的:

db.Posts.ensureIndex({"cDate.timestamp": 1}) 

還是同樣的問題。

+0

你嘗試在cDate.timestamp場添加索引。添加索引在這篇文章中提到,http://stackoverflow.com/questions/9730136/how-to-create-a-nested-index-in-mongodb'db.Posts.ensureIndex({「cDate.timestamp」:1 })' – Kishor

+0

好吧,讓我試試這個 – StormTrooper

+0

嘗試添加索引。不起作用。同樣的問題。瀏覽器卡住 – StormTrooper

回答

2

瀏覽器崩潰,因爲只有很多數據可以在其本身緩存之前加載到緩存中。對於您在需要大量文檔時會發生什麼的問題,請將該流程從客戶端移開,並通過優化的發佈和訂閱方法/調用在服務器上執行儘可能多的操作。沒有真正的理由在瀏覽器緩存中加載大量文檔,因爲minimongo的便利性適用於小型數據集以及不需要立即與服務器同步(或同步)的事物。

+0

好吧,告訴我如何顯示客戶端的分頁?我將如何顯示所有記錄的被動計數器?或者我將如何應用將從完整數據庫搜索的過濾器? – StormTrooper

+0

這很可能。首先,確定你將如何訂閱第一個案例中的帖子。聽起來像你正在從minimongo(這絕對符合流星最佳實踐)。 –

+0

因此,如果您要使用服務器/客戶端集合:您是在模板級別還是在路由器級別訂閱?你將使用什麼路由器?您是否發佈所有文檔,然後使用訂閱進行過濾?在進入分頁之前,需要先處理這些內容。有些人喜歡在這裏爲你做代碼 - 我想看看你能否給我們提供一些你所在的地方的代碼片段。如果你需要上述概念的幫助,那是另一回事,但我認爲你可以做到! –

2

你需要排序考慮和限制戰略是什麼:

排序,如果你在服務器上從所有客戶端使用的大集合中提取最高值。但是,通常需要數據的用戶首先進行過濾,然後對已過濾的集合進行排序。這將減少數據集。

然後發佈該分類/有限的子集到客戶端,你可以做更細粒度/排序篩選存在。

3

更改您的出版物,接受一個名爲pageNumber參數這樣

Meteor.publish('posts', function (pageNumber) { 
    var numberOfRecordsPerPage = 10; 
    var skipRecords = numberOfRecordsPerPage * (pageNumber - 1); 
    return Post.find({ 
     "user_id": user_id 
    }, { 
     sort: { 'cDate.timestamp': -1 } 
     skip: skipRecords, 
     limit: numberOfRecordsPerPage 
    }); 
}); 

在客戶端,我沒有角流星一樣工作。您可以使用this.pageNumber$scope.pageNumber在當前範圍下創建pageNumber屬性。只要您的分頁頁面被點擊,更新這個pageNumber變量。只要此變量發生更改,請使用當前頁碼進行訂閱。

如果是使用標準模板火焰,我會用一個autorun這樣的反應VAR或會話變種做到這一點。 在模板的html:

<template name="postsTemplate"> 
    <ul> 
     <!-- you would want to do this list based on total number of records --> 
     <li class="pagination" data-value="1">1</li> 
     <li class="pagination" data-value="2">2</li> 
     <li class="pagination" data-value="3">3</li> 
    </ul> 
</template> 

在模板JS:

Template.postsTemplate.created = function() { 
    var template = this; 
    Session.setDefault('paginationPage', 1); 
    template.autorun(function() { 
     var pageNumber = Session.get('paginationPage'); 
     Meteor.subscribe('posts', pageNumber); 
    }); 
} 

Template.postsTemplate.events(function() { 
    'click .pagination': function (ev, template) { 
     var target = $(ev.target); 
     var pageNumber = target.attr('data-value'); 
     Session.set('paginationPage', pageNumber); 
    } 
}); 

這樣,你會在客戶端上的任一時間點最多的10個記錄都有,所以它不會崩潰的瀏覽器。您可能還希望限制你使用這樣的事情

Meteor.publish('posts', function (pageNumber) { 
    var numberOfRecordsPerPage = 10; 
    var skipRecords = numberOfRecordsPerPage * (pageNumber - 1); 
    return Post.find({ 
     "user_id": user_id 
    }, { 
     sort: { 'cDate.timestamp': -1 } 
     skip: skipRecords, 
     limit: numberOfRecordsPerPage, 
     fields: {'message': 1, 'createdBy': 1, 'createdDate': 1 } //The properties inside each document of the posts collection. 
    }); 
}); 

發送到客戶端領域的最後,你將需要記錄的總數在帖子中收集的客戶端,以顯示分頁鏈接。您可以使用不同的發佈和使用observeChanges概念作爲正式文件here

// server: publish the current size of a collection 
Meteor.publish("posts-count", function() { 
    var self = this; 
    var count = 0; 
    var initializing = true; 

    // observeChanges only returns after the initial `added` callbacks 
    // have run. Until then, we don't want to send a lot of 
    // `self.changed()` messages - hence tracking the 
    // `initializing` state. 
    var handle = Posts.find({}).observeChanges({ 
    added: function (id) { 
     count++; 
     if (!initializing) 
     self.changed("postsCount", 1, {count: count}); 
    }, 
    removed: function (id) { 
     count--; 
     self.changed("postsCount", 1, {count: count}); 
    } 
    // don't care about changed 
    }); 

    // Instead, we'll send one `self.added()` message right after 
    // observeChanges has returned, and mark the subscription as 
    // ready. 
    initializing = false; 
    self.added("postsCount", 1, {count: count}); 
    self.ready(); 

    // Stop observing the cursor when client unsubs. 
    // Stopping a subscription automatically takes 
    // care of sending the client any removed messages. 
    self.onStop(function() { 
    handle.stop(); 
    }); 
}); 

// client: declare collection to hold count object 
PostsCount = new Mongo.Collection("postsCount"); 

// to get the total number of records and total number of pages 
var doc = PostsCount.findOne(); //since we only publish one record with "d == 1", we don't need use query selectors 
var count = 0, totalPages = 0; 

if (doc) { 
    count = doc.count; 
    totalPages = Math.ceil(count/10); //since page number cannot be floating point numbers.. 
} 

希望這有助於在提到做。

2

您應該使用服務器端限制而不是客戶端。這將使您的應用程序更快,更優化。

欲瞭解更多信息,請查看此鏈接。 link here