2014-01-06 5 views
12

일부 데이터를 표시해야하는 Meteor 템플리트가 있습니다. Deps afterFlush 기능에서다음 단계 전에 유성우 수집 대기 완료

예외 : 형식 오류 : 어떤 상황에서 Deps을 사용하지 않는 정의되지 않은

의 재산 '일'을 읽을 수 없습니다

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 
}; 

는 가끔 가끔이 오류가 작품 . 내가 알기에 컬렉션이 완전히로드되기 전에 참조되고 있습니다.

따라서 나는 단순히 "옮기기 전에 컬렉션을 찾을 때까지 기다리는"방법을 생각해 내고 싶습니다. 간단해야하지만 업데이트 된 솔루션을 찾을 수 없습니다.

답변

32

맞습니다. 데이터가 제대로로드 된 후 클라이언트 측 구독 컬렉션의 내용을 가져 오는 것에 따라 코드가 실행되도록해야합니다.

당신이 새로운 유성 1.0.4에 도입 된 패턴을 사용하여 달성 할 수있는 다음 Spacebars 템플릿 선언에서 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:router (https://github.com/iron-meteor/iron-router), 어떤이 제공하는 사용할 수 있습니다, 우리가 반드시 데이터를 클라이언트로의 길을 만들었 기 때문에이 시점에서 , 우리는 안전하게 svgTemplateonRendered 라이프 사이클 이벤트에 Pushups 수집을 조회 할 수 있습니다 이 일반적인 Meteor 관련 문제를 해결하기위한 또 다른 디자인 패턴으로, 템플릿 레벨 대신 경로 레벨에서 서브 스크립 션 처리를 이동하십시오.

프로젝트에 패키지를 추가

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(/*...*/); 
    } 
}); 

meteor add iron:router 
당신이 원하는 것을 얻을 플러스 추가 기능이 많이 있습니다 코드의 간단한 조각을 사용. Iron Router 가이드에서 이러한 기능에 대해 자세히 설명합니다.

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

편집 18/3/2015은 : 그것은 오래된 자료를 포함하고 여전히 그럼에도 불구하고 upvotes을 받았기 때문에 답을 재 작업.

+0

폭탄 엉덩이 응답 독 답변을 재 작업을위한 –

+0

감사 : 클라이언트 코드가 데이터를 가져 같은 방법을 사용할 수 있도록이 예에서는, 내 쿼리를 중앙 집중화합니다. 유성은 빠르게 움직이며 시대에 뒤 떨어진 많은 정보가 있습니다. –

+1

Meteor의 최신 릴리스에 반영된 디자인 패턴 인 템플릿 수준 가입을 사용하기 위해 다시 답을 수정했습니다. – saimeunt

3

이것은 내가 직접적으로 언급 한 기본적인 유성 문서를 원했던 문제 중 하나입니다.그 이유는 다음과 같습니다.

  1. API에 따라 올바른 작업을 수행했습니다.
  2. 루트 문제를 나타내지 않는 Deps의 오류가 발생합니다.

이미 알았 듯이 템플릿을 렌더링 할 때 데이터가 준비되지 않았습니다. 가장 쉬운 솔루션은 무엇입니까? 데이터가 준비되지 않았다고 가정합니다. examples은 이것을 많이합니다. leaderboard.js에서 :

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

player 실제로 발견되는 경우에만, player.name 액세스 할 수 있습니다. coffeescript에서는 같은 것을 달성하기 위해 담금질을 사용할 수 있습니다.

iron-router 님의 제안은이 특별한 사용 사례에 좋지만 데이터가 데이터베이스에 존재하지 않는 상황이나 원하는 속성이있는 상황에 부딪 힐 가능성이 매우 높습니다. 가져온 개체에 존재하지 않습니다.

불행한 현실은 많은 경우에 방어 프로그래밍이 필요하다는 것입니다.

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()); 
관련 문제