2014-01-06 4 views
12

私はいくつかのデータを表示するはずの流星テンプレートを持っています。流星集合が次のステップの前に終了するのを待つ

Template.svg_template.rendered = function() { 
    dataset_collection = Pushups.find({},{fields: { date:1, data:1 }}, {sort: {date: -1}}).fetch(); 

    a = moment(dataset_collection[0].date, "YYYY/M/D"); 
    //more code follows that is also dependent on the collection being completely loaded 
}; 

時にはそれは時々私はこのエラーを取得し、作品:DEPS afterFlush機能から

例外:例外TypeError:未定義

のプロパティを読み取ることができません「日付」私は任意のコンテキストでのDEPを使用していませんよ。私が理解しているように、コレクションは完全にロードが完了する前に参照されています。

私は、単に「コレクションが移動する前に見つかるまで待つ」という言い方をしたいと思います。簡単なはずですが、更新された解決策が見つかりません。

答えて

32

データが正しく読み込まれた後に、クライアント側の購読済みコレクションのコンテンツを取得することに応じたコードが実行されるようにする必要があります。あなたは流星1.0.4で導入された新しいパターン使用してこれを達成することができます

:宇宙・天体バーテンプレート宣言でhttps://docs.meteor.com/#/full/Blaze-TemplateInstance-subscribe

client/views/svg/svg.js

Template.outer.onCreated(function(){ 
    // subscribe to the publication responsible for sending the Pushups 
    // documents down to the client 
    this.subscribe("pushupsPub"); 
}); 

client/views/svg/svg.html

<template name="outer"> 
    {{#if Template.subscriptionsReady}} 
    {{> svgTemplate}} 
    {{else}} 
    Loading... 
    {{/if}} 
</template> 

を、我々はカプセル化を使用しますouterテンプレートレベルのサブスクリプションパターンを処理するテンプレート。 ライフサイクルイベントのonCreatedの購読を購読しており、特別なリアクティブヘルパーTemplate.subscriptionsReadyを使用して、購読が準備完了(データはブラウザで利用可能)になったらsvgTemplateをレンダリングするだけです。

また
Template.svgTemplate.onRendered(function(){ 
    console.log(Pushups.find().fetch()); 
}); 

、あなたが提供する、iron:routerhttps://github.com/iron-meteor/iron-router)を使用することができます この時点で、私たちは、安全に、我々は必ずデータがクライアントにその方法を作ったためsvgTemplateonRenderedライフサイクルイベントでPushupsコレクションを照会することができますMeteorに関連するこの共通の問題を達成するための別のデザインパターン。テンプレートレベルではなくルートレベルでのサブスクリプション処理の移動。あなたが望む結果を得るでしょう、このコードのシンプルな作品に加えて追加機能の多くを使用して

meteor add iron:router 

lib/router.js

Router.route("/svg", { 
    name: "svg", 
    template: "svgTemplate", 
    waitOn: function(){ 
    // waitOn makes sure that this publication is ready before rendering your template 
    return Meteor.subscribe("publication"); 
    }, 
    data: function(){ 
    // this will be used as the current data context in your template 
    return Pushups.find(/*...*/); 
    } 
}); 

プロジェクトにパッケージを追加します。 Iron Routerのガイドでは、これらの機能について詳しく説明しています。

https://github.com/iron-meteor/iron-router/blob/devel/Guide.md

EDIT 18/3/2015:それは時代遅れの材料が含まれているため、答えを再加工し、まだそれにもかかわらずupvotesを受けました。

+0

爆弾尻回答ドッグあなたの答えを作り直すため –

+0

ありがとう:クライアントコードはデータを引き出すために、同じ方法を使用することができますので、この例はまた、私のクエリを一元化します。流星は速く動き、古くなった情報がたくさんあります。 –

+1

Meteorの最新リリースに入ったデザインパターンであるテンプレートレベルのサブスクリプションの使用を奨励するために、この回答を再作成しました。 – saimeunt

3

これは私が本当に基本的な流星文書が直接取り上げてくれることを望んでいる問題の一つです。これは混乱しています。

  1. APIに従って正しいことを行いました。
  2. Depsのエラーは、ルートの問題を指摘していません。

既に分かっているように、テンプレートがレンダリングされると、データは準備ができていません。最も簡単な解決策は何ですか?データが準備できていない可能性があるとします。 examplesはこれをたくさん行います。 leaderboard.jsから:playerが実際に発見された

Template.leaderboard.selected_name = function() { 
    var player = Players.findOne(Session.get("selected_player")); 
    return player && player.name; 
}; 

場合のみ、player.nameアクセスされます。 coffeescriptでは、同じことを達成するために浸漬を使用することができます。

iron-routerの提案waitOnは、この特定の使用例には適していますが、データがデータベースに存在しない状況、または必要なプロパティフェッチされたオブジェクトには存在しません。

不幸な現実は、これらのケースの多くで防御プログラミングのビットが必要であるということです。

0

Iron-Routerを使用してサブスクリプションを使用することはできますが、サブスクリプションはcollections.jsファイルのように集中管理しておくことができます。代わりに、私はMeteorのfile load orderを利用して、それ以外のものより先にサブスクリプションをロードします。それは私の典型的なクライアントコードの前にロードされますように、私はその後、lib/フォルダにcollections.jsを入れ

// ****************************** Collections ********************************** 
Groups = new Mongo.Collection("groups"); 

// ****************************** Methods ************************************** 
myGroups = function (userId) { 
    return Groups.find({"members":{$elemMatch:{"user_id":userId}}}); 
}; 

// ****************************** Subscriptions ******************************** 
if(Meteor.isClient){ 
    Meteor.subscribe("groups"); 
} 

// ****************************** Publications ********************************* 
if(Meteor.isServer){ 
    Meteor.publish("groups", function() { 
    return myGroups(this.userId); 
    }); 
} 

は、ここに私のcollections.jsファイルがどのようなものであるかです。そうすることで、サブスクリプションは、私のルートの一部ではなく、単一のcollections.jsファイルに集約されます。

var groups = myGroups(Meteor.userId()); 
関連する問題