2013-05-01 33 views
6

Tại sao trong ví dụ cơ bản sau, bộ sưu tập trả về bên trong hàm được hiển thị bị trống?
Tự động xuất bản được bật. Sau khi tải trang lệnh
Coll.find().fetch() gọi bên trong javascript console lợi nhuận đúng thiết lập các mụcMeteor template.rendered - Tại sao bộ sưu tập trống?

Đây là mã

t.js

Coll = new Meteor.Collection("coll"); 

if (Meteor.isClient) { 
    Template.tpl.rendered = function(){ 
    console.log(Coll.find().fetch()); // <-- This line prints empty array 
    }; 
} 

if (Meteor.isServer) { 
    Meteor.startup(function() { 
     if (Coll.find().count() === 0) { 
      var f = ["foo","bar"]; 
      for (var i = 0; i < f.length; i++) 
       Coll.insert({f: f[i]}); 
     } 
    }); 
} 

t.html tập tin

<head> 
    <title>test</title> 
</head> 

<body> 
    {{> tpl}} 
</body> 

<template name="tpl"> 
    Test tpl 
</template> 
+0

Đó là do bộ sưu tập của bạn chưa được tải. 'Template.rendered' được kích hoạt, không có nghĩa là bộ sưu tập của bạn được tải. kiểm tra [this] (http://stackoverflow.com/questions/15129827/) thread. –

Trả lời

5

Meteor được xây dựng tắt của một loại dữ liệu-on-the dây structu lại. Điều này có nghĩa là khi ứng dụng tải ban đầu HTML & JS được gửi xuống trước và sau đó là dữ liệu.

Bạn phải sử dụng tính phản ứng để kiểm tra các thay đổi dữ liệu hoặc kiểm tra khi đăng ký bộ sưu tập hoàn tất (yêu cầu xóa gói tự động xuất bản). (Bạn có thể kiểm tra làm thế nào để di chuyển ứng dụng của bạn để một thuê bao tay tại các tài liệu: http://docs.meteor.com/#publishandsubscribe)

Việc gọi lại thuê bao cho bạn biết khi dữ liệu được trả về:

Meteor.subscribe("coll", function() { 
    //Data subscription complete. All data is downloaded 
}); 

Mẫu cũng có thể được thực hiện phản ứng (giống như cách bạn đang làm) nhưng .rendered không được gọi vì trước tiên Meteor kiểm tra xem html của mẫu có thay đổi & chỉ khi nó khác nhau nó sẽ thay đổi HTML của nó và gọi hàm trả lại được hiển thị.

Những gì bạn có như một tùy chọn ở đây là 1) sử dụng Deps.autorun thay vào đó, hoặc

2) Tôi không chắc chắn lý do tại sao bạn đang sử dụng này trong callback render của bạn, nhưng nếu nó là cần thiết để đặt nó ở đó bạn cần phải đảm bảo rằng HTML của mẫu thay đổi, bằng cách giới thiệu một cái gì đó vào html từ bộ sưu tập của bạn mà làm cho nó thay đổi khi dữ liệu mới được giới thiệu.

+0

Tôi cũng bị kẹt ở đây. bạn có thể xây dựng trên này? Tôi đang cố gắng để tự render một mẫu mà tạo ra một biểu đồ js c3 và đang cố gắng tải dữ liệu từ cơ sở dữ liệu nhưng nhận được mảng trống như trên. – radtek

+0

@radtek Meteor hoạt động bằng cách gửi html đầu tiên, sau đó là dữ liệu sau. Khi cuộc gọi lại được kích hoạt, dữ liệu có thể không được gửi hoặc có thể đã được gửi. Bạn phải đảm bảo một điều gì đó để đảm bảo rằng bạn đợi cho đến khi sử dụng một trong các phương pháp trên hoặc lệnh 'subscribe (' .. ') của bộ định tuyến sắt. Lệnh wait() 'trước khi bạn vẽ biểu đồ. – Akshat

+0

Vâng, tôi biết điều đó. Tôi đoán những gì tôi sau là một ví dụ về gói meteor c3 js đang sử dụng. Hoạt động tốt với dữ liệu tĩnh nhưng phải có một ví dụ thực hành tốt nhất để làm việc với dữ liệu db. Tôi sẽ xem những gì tôi đưa ra sau tối nay. Khi tôi cố gắng render html sau đó đăng ký và đưa dữ liệu qua handlebars, tôi đã cố gắng tạo ra một kịch bản lệnh js bên trong bản mẫu, nhưng các thanh ghi sẽ tạo một dòng mới khi tôi thực hiện cho mỗi vì vậy nó không phải là js phân tích được. var data = []; data.push ({{each_item}}); . Vì vậy, sau đó tôi nghĩ rằng đây là cách quá hacky và có cần phải là một cách tốt hơn – radtek

Các vấn đề liên quan