为什么 Collection.find() 在我的 Meteor 客户端上不起作用?
Why is Collection.find() not working on my Meteor client?
我确定正确地创建了我的 collection、发布数据、订阅正确的出版物,并检查数据是否确实出现在 Mongo Shell 中。我什至 console.log()' 了正在发布的数据,以确保发布工作正常。然而,以下代码行无法 return 任何东西:
const maybeMeet = Meets.find({meetId: maybeId}).fetch();
这可以在下面和链接存储库 /client/imports/routes/routes.js
的第 39 行中找到。
有一次,我什至尝试创建一个新的 Meteor 方法 'meets.query'
,它只会发布我需要的所有数据,(不安全地)避免对发布和订阅的需要(现在它被注释掉了/client/imports/api/meets.js
的第 59 行)。那也没有用。一般来说,客户端似乎无法从服务器接收任何数据,但从客户端到服务器似乎可以工作(我可以将东西插入我的 Meets collection)。
这里是问题的根源(routes.js
的一部分):
export const routes = (
<div id='app'>
<Header />
<Router history={browserHistory}>
<Switch>
<Route exact path="/" render={() => {
return <Landing />
}} />
<Route path="/before" render={() => {
return <Before />
}} />
<Route path="/meet" render={() => {
Meteor.subscribe('allMeets');
const maybeId = queryString.parse(location.search).m;
console.log(typeof maybeId);
console.log(maybeId);
const maybeMeet = Meets.find({meetId: maybeId}).fetch(); //***RETURNS NOTHING!***
return maybeMeet.length ? <Created meet={maybeMeet[0]} /> : <NotFound />;
}} />
<Route path="*" render={() => {
return <NotFound />
}} />
</Switch>
</Router>
</div>
);
这是我发布数据的地方(`meets.js' 的一部分):
if (Meteor.isServer) {
Meteor.publish('allMeets', function() {
return Meets.find();
});
}
如果您需要查看更多信息,请查看完整代码的存储库:https://github.com/kpeluso/meetr
对于混乱的代码,我深表歉意 - 这是一个新项目。
这里的问题是订阅操作是异步的,因为它必须从服务器获取数据。
解决方案是将路由器渲染的组件包裹在一个WithTracker
中,这样它会在数据可用时重新运行并开始渲染到DOM
有关如何执行此操作的更多信息,请参见文档:
https://guide.meteor.com/react.html#using-withTracker
在我的 Created
组件中,我有一个 Tracker.autorun()
有一个错误,导致其他一切崩溃。如前所述,在我的路由器中对 Meteor.subscribe(allMeets);
的调用也是异步的,并且没有被这样处理。
我发现 withTracker
很麻烦,但我从它的文档中获得了很多灵感。因此,我的 Created
组件中编辑后的代码现在包括:
componentDidMount() {
this.meetTracker = Tracker.autorun(() => {
const subHandle = Meteor.subscribe('allMeets');
const loading = !subHandle.ready();
const maybeMeet = Meets.find({meetId: this.props.meetId}).fetch();
if (!maybeMeet.length && loading) {
this.setState({active: <Loading />});
} else if (!loading) {
if (maybeMeet.length) {
this.setState({active: <During meet={maybeMeet[0]} />});
} else {
createHistory().push('/PageNotFound');
window.location.reload();
}
}
});
}
...我的 router
中的代码现在包括:
<Route path="/meet" render={() => {
const maybeId = queryString.parse(location.search).m;
return <Created meetId={maybeId} />
}} />
WithTracker,检查流星文档https://guide.meteor.com/react.html#using-withTracker
例如,在这段代码中,对于 APP 组件,withTracker 保持反应与订阅同步,事物列表获取集合。
export default withTracker(() => {
Meteor.subscribe('allThings')
return {
things: Things.find({}).fetch()
}
})(App);
查看我的流星反应样板文件。
https://github.com/pkcwong/meteor-react-starter
我使用包meteor/react-meteor-data
。 HOF withTracker
是正确的解决方案。
我确定正确地创建了我的 collection、发布数据、订阅正确的出版物,并检查数据是否确实出现在 Mongo Shell 中。我什至 console.log()' 了正在发布的数据,以确保发布工作正常。然而,以下代码行无法 return 任何东西:
const maybeMeet = Meets.find({meetId: maybeId}).fetch();
这可以在下面和链接存储库 /client/imports/routes/routes.js
的第 39 行中找到。
有一次,我什至尝试创建一个新的 Meteor 方法 'meets.query'
,它只会发布我需要的所有数据,(不安全地)避免对发布和订阅的需要(现在它被注释掉了/client/imports/api/meets.js
的第 59 行)。那也没有用。一般来说,客户端似乎无法从服务器接收任何数据,但从客户端到服务器似乎可以工作(我可以将东西插入我的 Meets collection)。
这里是问题的根源(routes.js
的一部分):
export const routes = (
<div id='app'>
<Header />
<Router history={browserHistory}>
<Switch>
<Route exact path="/" render={() => {
return <Landing />
}} />
<Route path="/before" render={() => {
return <Before />
}} />
<Route path="/meet" render={() => {
Meteor.subscribe('allMeets');
const maybeId = queryString.parse(location.search).m;
console.log(typeof maybeId);
console.log(maybeId);
const maybeMeet = Meets.find({meetId: maybeId}).fetch(); //***RETURNS NOTHING!***
return maybeMeet.length ? <Created meet={maybeMeet[0]} /> : <NotFound />;
}} />
<Route path="*" render={() => {
return <NotFound />
}} />
</Switch>
</Router>
</div>
);
这是我发布数据的地方(`meets.js' 的一部分):
if (Meteor.isServer) {
Meteor.publish('allMeets', function() {
return Meets.find();
});
}
如果您需要查看更多信息,请查看完整代码的存储库:https://github.com/kpeluso/meetr
对于混乱的代码,我深表歉意 - 这是一个新项目。
这里的问题是订阅操作是异步的,因为它必须从服务器获取数据。
解决方案是将路由器渲染的组件包裹在一个WithTracker
中,这样它会在数据可用时重新运行并开始渲染到DOM
有关如何执行此操作的更多信息,请参见文档: https://guide.meteor.com/react.html#using-withTracker
在我的 Created
组件中,我有一个 Tracker.autorun()
有一个错误,导致其他一切崩溃。如前所述,在我的路由器中对 Meteor.subscribe(allMeets);
的调用也是异步的,并且没有被这样处理。
我发现 withTracker
很麻烦,但我从它的文档中获得了很多灵感。因此,我的 Created
组件中编辑后的代码现在包括:
componentDidMount() {
this.meetTracker = Tracker.autorun(() => {
const subHandle = Meteor.subscribe('allMeets');
const loading = !subHandle.ready();
const maybeMeet = Meets.find({meetId: this.props.meetId}).fetch();
if (!maybeMeet.length && loading) {
this.setState({active: <Loading />});
} else if (!loading) {
if (maybeMeet.length) {
this.setState({active: <During meet={maybeMeet[0]} />});
} else {
createHistory().push('/PageNotFound');
window.location.reload();
}
}
});
}
...我的 router
中的代码现在包括:
<Route path="/meet" render={() => {
const maybeId = queryString.parse(location.search).m;
return <Created meetId={maybeId} />
}} />
WithTracker,检查流星文档https://guide.meteor.com/react.html#using-withTracker
例如,在这段代码中,对于 APP 组件,withTracker 保持反应与订阅同步,事物列表获取集合。
export default withTracker(() => {
Meteor.subscribe('allThings')
return {
things: Things.find({}).fetch()
}
})(App);
查看我的流星反应样板文件。
https://github.com/pkcwong/meteor-react-starter
我使用包meteor/react-meteor-data
。 HOF withTracker
是正确的解决方案。