- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我不知道这更多的是 React 还是 Meteor 问题,也许两者都有,但我目前正在使用这两个框架构建一个网络应用程序,我面临着程序员的问题。我不是 Javascript 开发人员,而是 Java 开发人员(我每天使用 GWT),所以也许我犯了一些菜鸟错误。
我的应用程序不断增长,我有越来越多的 React 组件,大约有二十个左右。现在我有了一个很好的 View ,我已经向我的组件添加了一些功能,但事实证明我在 React 组件中添加了越来越多的逻辑,我认为这违反了 MVC 原则。
但是,我不知道如何移动“Meteor Controller 组件”中的逻辑。现在,我使用 Meteor 作为其模型,仅此而已。我多次看到这个Pete Hunt's talk以及他如何构建他的应用程序,但它只有一个“简单”组件。
事实上,如果没有 React, View 将位于使用模板定义的 html 文件中。 Controller 将位于 js 文件中,并且逻辑将出现在那里。我可以清楚地看到 View 和 Controller 之间的分割。
Html 文件(来自排行榜示例):
<template name="leaderboard">
...
</template>
<template name="player">
<div class="player {{selected}}">
...
</div>
</template>
Javascript 文件(来自排行榜示例):
...
Template.leaderboard.players = function () {
return Players.find({}, {sort: {score: -1, name: 1}});
};
Template.leaderboard.selected_name = function () {
var player = Players.findOne(Session.get("selected_player"));
return player && player.name;
};
...
由于 React 是 javascript,因此将我们想要的所有内容放入 React 组件中非常简单且诱人。
我知道这些框架对每个人来说都相对较新,但我想知道是否存在一些关于如何设计这样的 MVC 应用程序以便拥有灵活且可维护的 Web 应用程序的约定,有什么可遵循的准则吗?我不是在寻找“最佳”方法,而是寻求一些意见。
注意:我故意不在此处放置大量代码,以免集中注意力,但请随意用您想要的任何内容(代码、架构、链接...)来说明您的答案。
<小时/>这是我正在做的事情的一个例子。在这个例子中,一切都是在 react 类中完成的,也许这是最好的方法,也许不是,我需要你的想法。
总而言之,它从作为输入给出的数组创建一个元素列表(Boostrap 列表组)(类似于 [{name: itemName1, type:itemType1}, {name: itemName2, type:itemType2} ... ] 生成如下 View :
每个项目根据其类型都有自己的风格。然后通过输入文本框,用户可以对该列表进行搜索,它会过滤该列表并生成一个由匹配元素组成的新列表(搜索算法不正确,将被更改)。另外,还有某些键盘按键的附加命令。一切都工作正常,但正如你所注意到的,一切都在 React 类中,我不知道如何将 Meteor 与 React 结合起来。
meteor 文件:
if (Meteor.isClient) {
Meteor.startup(function() {
//Build the view
React.renderComponent(
<Search items={initialItems}/>,
document.getElementById('main')
);
});
}
react 文件:
Search = React.createClass({
getInitialState : function() {
return (
{
items : flat(this.props.items),
active : 0
}
);
},
setListVisibility: function(visibility) {
this.refs.list.getDOMNode().style.visibility = visibility;
},
onchangeHandler: function() {
var re = new RegExp(this.refs.search.getDOMNode().value, "i");
var res = [];
//filter on props.items and not state.items
flat(this.props.items).map(function(item){
if(item.name.search(re) >= 0)
res.push(item);
});
this.setState({ items : res, active : 0});
},
onkeydownHandler: function(event){
if(event.key == "ArrowDown" || event.key == "ArrowUp"){
var shift = event.key == "ArrowDown" ? 1 : -1;
var newActive = this.state.active + shift;
if(newActive >= 0 && newActive < this.state.items.length)
this.setState({ active : this.state.active + shift });
} else if(event.key == "ArrowRight"){
if(this.state.items.length > 0){
var item = this.state.items[this.state.active];
var newItems = retrieveItem(this.props.items, item.name, typeToSubType[item.type]);
newItems = flat(newItems);
if(newItems.length > 0)
this.setState({ items : newItems, active : 0 });
}
} else if(event.key == "ArrowLeft"){
this.setState({ items : flat(this.props.items), active : 0});
} else if(event.key == "Enter"){
if(this.state.items.length > 0){
var item = this.state.items[this.state.active];
console.log("Add "+item.name+" "+item.type+" to the view");
}
}
},
render: function () {
return (
<div>
<nav className="navbar navbar-default" role="navigation">
<div className="container-fluid">
<div className="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<form className="navbar-form navbar-left" role="search">
<div className="form-group">
<input ref="search" type="text" className="form-control" placeholder="Search" size="100"
onChange={this.onchangeHandler}
onKeyDown={this.onkeydownHandler}
onFocus={this.setListVisibility.bind(this, "visible")}
onBlur={this.setListVisibility.bind(this, "hidden")}/>
</div>
</form>
</div>
</div>
</nav>
<List ref="list" items={this.state.items} active={this.state.active}/>
</div>
);
}
});
List = React.createClass({
render: function () {
var createItem = function(item, index) {
var cl = "list-group-item";
if(index == this.props.active)
cl += " active";
var gly = "glyphicon ";
switch(item.type){
case "dimension":
gly += "glyphicon-certificate";
break;
case "hierarchy":
gly += "glyphicon-magnet";
break;
case "level":
gly += "glyphicon-leaf";
break;
case "measure":
gly += "glyphicon-screenshot";
break;
}
return (<a href="#" className={cl} key={item.type+"/"+item.name}>
<span className={gly}></span>{" "}{item.name}
</a>);
};
return (
<div className="list-group search-list">
{this.props.items.map(createItem, this)}
</div>
);
}
});
最佳答案
你的方法是正确的:Meteor 用于模型,React 用于 View 和 ViewController。
任何与表示无关的功能都应该在模型中(业务逻辑、验证规则等)。
与演示和响应用户输入有关的任何内容都应该在 React 中(输入、验证输出等)。
关于javascript - 如何让 React 和 Meteor 结合在一起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22181413/
我是一名优秀的程序员,十分优秀!