2015-10-04 85 views
1

我已經根據優秀的Meteor Kitchen項目生成的代碼構建了一個小型流星應用。這段代碼工作並將集合呈現給頁面,但有一件事我很困惑。爲什麼在一個鐵路路由器控制器中調用collection.find

代碼的子集是在這裏:

router.js

this.route("articles", {path: "/articles", controller: "ArticlesController"}); 

ArticlesController

this.ArticlesController = RouteController.extend({ 
    template: "Articles", 

    onBeforeAction: function() { 
     this.next(); 
    }, 

    action: function(){ 
     if (this.isReady()) { 
     this.render(); 
     } else { 
     this.render("loading"); 
     } 
    }, 

    isReady: function() { 
     var ready = true; 
     var subs = [ Meteor.subscribe('allArticles') ]; 
     _.each(subs, function(sub) { 
     if(!sub.ready()) 
      ready = false; 
     }); 
     return ready; 
    }, 

    data: function() { 
     return { 
     articles: Articles.find({}) 
     }; 
    } 
}); 

服務器/酒吧/ articles.js

Meteor.publish('allArticles', function() { 
    return Articles.find({}); 
}); 


Meteor.publish('singleArticle', function(articleId) { 
    check(articleId, String); 
    return Articles.find({_id: articleId}); 
}); 

據我瞭解這段代碼是如何工作的,發生以下情況:

(1)收集通過allArticlessingleArticle發表訂閱
(2)ArticlesController訂閱allArticles
(3)數據函數在ArticlesController中提取數據(從訂閱?)到文章數組whi然後將h暴露給Blaze模板。

我困惑的地方: 爲什麼我們需要在數據函數中做一個Articles.find({})?我們在哪裏訪問全部文章數據...似乎我們將直接回到文章收藏,如果我們僅訂閱了全部文章,那麼這可能會怎樣?

回答

3

雖然你沒有表現出來,我假設你在你的下面一行代碼,定義的地方將執行它在服務器上,客戶端:

Articles  = new Mongo.Collection('articles'); 
/*CollectionName = new Mongo.Collection('DBCollectionName');*/ 

Docs.當這在創建集合的服務器上執行,並分配給變量名稱Articles。 'articles'是用於在MongoDB中存儲這個集合的名稱。

在客戶端上執行此操作時,會創建一個迷你mongo集合。它最初將沒有文件。

接下來你唯一的服務器代碼:

Meteor.publish('allArticles', function() { 
    return Articles.find({}); 
}); 

Meteor.publish('singleArticle', function(articleId) { 
    check(articleId, String); 
    return Articles.find({_id: articleId}); 
}); 

Docs.這定義了兩個出版物, 'allArticles' 和 'singleArticle'。這些不是集合本身,而是指定服務器將發佈的一組數據的規則,並且客戶端可能會訂閱這些數據。雖然這兩個發佈從Server的Articles集合返回數據,但發佈可以從一個或多個集合返回數據,或者直接使用基礎ddp協議發佈來自其他數據源(而不是mongodb)的數據。

下一頁您訂閱的集合在客戶端上:

Meteor.subscribe('allArticles') 

Docs.此調用都在服務器(「allArticles」)上定義了發佈的名稱,並訂閱它。服務器然後執行發佈功能,並通過ddp發送返回的數據集。這些數據存儲在上面創建的客戶端Mini Mongo Collection中,並命名爲Articles。

此外,服務器將監視Articles集合中的更改,如果'allArticles'發佈的結果集發生更改,則會將這些更改作爲更新發送到客戶端。

所以接下來你在你的控制器(客戶端)有數據功能。

data: function() { 
    return { 
    articles: Articles.find({}) 
    }; 
} 

Docs.這設置了渲染功能的數據上下文。

這個調用articles.find而不是allArticles.find的原因是因爲allArticles不是一個集合,而是客戶端用於請求服務器發送數據的發佈名稱,存儲在客戶端mini mongo集合命名文章。

+0

多麼令人難以置信的答案。如果可以的話,我會投它兩次。這部分對我來說完全有意義「存儲在客戶迷你mongo集合中的文章。」 – ardochhigh

+0

@ardochhigh謝謝! – JeremyK

0

我需要更多地瞭解您的應用才能回答問題。你只查看一篇文章,還是有一個列出所有文章的頁面?

如果您正在查看單個文章,您需要訂閱singleArticle發佈。

如果您正在顯示列表的文章,您需要訂閱allArticles。如果有很多文章,可以通過將字段的數量限制爲query projection來提高應用的速度。

+0

我不認爲這是詢問者打算何時使用每個出版物 – challett

1

我們在哪裏訪問allArticles數據...看來我們是直接回去 公司章程的收集和如何是可能的,如果我們 訂閱只allArticles?

您將此作爲數據對象的一部分返回,以便您可以在模板中對其進行訪問。在您的Articles模板中,您現在可以直接使用{{#each articles}}而無需幫助器功能,因爲articles是您的數據上下文的一部分。您還可以使用this.articles訪問您的Articles模板助手內部控制器data部分返回的文章。

爲什麼我們需要在數據函數中執行Articles.find({})?

這些正在您的控制器數據函數中執行的查詢作用於客戶端minimongo文章集合,而不是服務器。一旦信息從服務器發佈,並且客戶端已經訂閱了它,客戶端在minimongo實例中有這個信息,但仍然需要以某種方式訪問​​它。基本上,出版物使信息可用,但Articles.find({})爲客戶端訪問它。

在您的控制器的數據功能內部訪問此信息只是爲了避免在模板內部執行此操作。

我認爲你的誤解來自於你所描述的第三步:在ArticlesController

數據功能提取數據(從 訂閱?)的文章數組,然後將其暴露於 Blaze模板。

數據函數從包含訂閱信息的客戶端上的minimongo中提取數據。 Minimongo位於訂閱和數據功能之間。