我正在使用Meteor和React作为视图层。有人知道或知道使用这种组合查询本地客户端集合并在React组件之间作为道具传递数据的例子吗?
我说的是一个类似于客户端组件的东西,它有:
const flashMessages = new Mongo.Collection(null)
以及一些方法,如添加、删除等。然后如何最好地在当前或另一个React组件中显示这些数据。我在Blaze中发现了几个这样的例子,但在React中没有。我不确定在这种情况下数据是否/如何反应,也不确定是否需要像getMeteorData()
这样的东西。
任何关于如何最好地处理这种组合的建议或例子都将非常棒!
对于其他可能对此感兴趣的人,以下是我要做的工作。我有一个消息模块,但您可以将此原则应用于您想要或需要的任何其他类型的集合:
const Messages = {
// Local (client-only) collection
collection: new Mongo.Collection(null),
addMessage(message, level) {
// set default type to error
level = (typeof level === 'undefined') ? 'error': level;
// Store in the local collection
this.collection.insert({message: message, level: level, isDialog: false});
},
addDialogMessage(message, level) {
// set default type to error
level = (typeof level === 'undefined') ? 'error': level;
// Store in the local collection
this.collection.insert({message: message, level: level, isDialog: true});
},
removeMessage(messageId) {
this.collection.remove(messageId);
},
clearMessages() {
let messages = this.collection.find({}).fetch()
messages.map((message) =>
this.collection.remove(message._id)
)
}
};
export default Messages
这里包含"数据库"方法。然后在我的情况下,我有一个显示该数据的an instance
的组件:
import { Component, PropTypes } from 'react'
import ReactMixin from 'react-mixin'
import Messages from 'common/client/components/flash/MessageTest'
@ReactMixin.decorate(ReactMeteorData)
export default class EpFlash extends Component {
getMeteorData() {
let messages
if (this.props.isDialog) {
messages = Messages.collection.find({isDialog: true}).fetch()
}else{
messages = Messages.collection.find({isDialog: false}).fetch()
}
return {
messages
}
}
remove = (id) => {
Messages.removeMessage(id)
}
render() {
let styles = {
error: {color: '#fff', background: '#a94442',
textAlign: 'center', marginBottom: '5px'},
warning: {color: '#fff', background: '#f0ad4e',
textAlign: 'center', marginBottom: '5px'},
info: {color: '#fff', background: '#337ab7',
textAlign: 'center', marginBottom: '5px'},
success: {color: '#fff', background: '#5cb85c',
textAlign: 'center', marginBottom: '5px'}
}
return (
<div>
{this.data.messages.map((message, index) =>
<div key={index}>
<span className="cute-row"
style={styles.error}>
{message.message}
<span onClick={this.remove.bind(this, message._id)}
style={{float: 'right', cursor: 'pointer', paddingRight: '5px'}}>
<i>×</i>
</span>
</span>
</div>
)}
</div>
);
}
}
在这里,你可以应用动画、超时或其他任何东西,因为React,你使用的每个地方都是它自己的组件实例。我将使示例中的类成为动态的,但还没有实现。我把它们留在里面是为了让你了解什么是可能的。
然后,无论在哪里使用它,都可以将它与数据库模块中的方法相结合,以获得所需的任何内容。如果你在两个不同的选项卡或窗口中运行这个,你会看到每个选项卡或窗口都有自己的实例。您可能对此很感兴趣,但请记住,集合在页面刷新或浏览器关闭时会被擦除,因此,如果您需要为实例预先填充任何内容,则需要在类似componentWillMount()
的程序中执行。为了安全起见,我还会清除ComponentWillUnmount()
或某个地方的每个实例。
import { Component, PropTypes } from 'react'
import Messages from 'common/client/components/flash/MessageTest'
import EpFlash from 'common/client/components/flash/EpFlash'
export default class Wrapper extends Component {
add = () => {
Messages.addMessage('crap', 'error')
}
addDialog = () => {
Messages.addDialogMessage('dialog crap', 'error')
}
clear = () => {
Messages.clearMessages()
}
render() {
return (
<div>
<h3>Messages</h3>
<EpFlash isDialog={true}/>
<button onClick={this.add}>Add</button>
<button onClick={this.addDialog}>Add Dialog</button>
<button onClick={this.clear}>Clear</button>
</div>
)
}
}
这只是一个有改进空间的简单原型,但它很有效,希望能给其他对这类东西感兴趣的人一个起点。
p.S.getMeteorData在Meteor 1.3中更改为createContainer。此示例基于1.2,因为1.3是全新的。