使用BackBone + React开发web应用 – 使用Backbone的Model作为数据存储
在开发web应用时,使用Model来组织数据是一种非常有效的方式。在本文中,我们将使用Backbone的Model来存储数据,而使用React来开发视图部分。
Backbone Model
Backbone的Model类提供了一些非常方便的添加数据和存储数据的方法,并且支持通过事件监听和自动/手动触发,在本文的例子中,我们将使用Backbone的Model来存储用户的信息,包括姓名,性别以及头像链接。代码如下所示:
<!doctype html>
<html lang="en">
<head>
<script src="jquery-2.0.3/build/jquery.js"></script>
<script src="underscore-1.5.2/build/underscore.js"></script>
<script src="backbone-1.1.0/build/backbone.js"></script>
</head>
<body>
<script type="text/javascript">
var Profile = Backbone.Model.extend({
defaults : {
name : null,
gender : null,
picture : null
}
});
var profile = new Profile({
name : "Christopher Pitt",
gender : "male",
picture : "http://placekitten.com/200/200"
});
console.log(
"name : " + profile.get("name") + "\n" +
"gender : " + profile.get("gender") + "\n" +
"picture : " + profile.get("picture")
);
</script>
</body>
</html>
在上面的代码中,我们定义了默认属性值。然后通过new
运算符实例化了一个Profile实例。
值得一提的一点是,我们在获取数据的时候使用了get()
方法,这样一来,我们并不会直接去接触数据,这保证了数据的安全性,同时我们也可以通过set()
方法来自动触发Model中的事件。
渲染模型
现在我们已经有了存储数据的模型,我们现在就来为这个Profile模型创建一个对应的React组件。
<!doctype html>
<html lang="en">
<head>
<script src="jquery-2.0.3/build/jquery.js"></script>
<script src="underscore-1.5.2/build/underscore.js"></script>
<script src="backbone-1.1.0/build/backbone.js"></script>
<script src="react-0.8.0/build/react.js"></script>
<script src="react-0.8.0/build/JSXTransformer.js"></script>
<style>
body {
padding : 20px;
font-family : helvetica, arial;
}
.picture {
margin : 0 0 10px 0;
}
</style>
</head>
<body>
<script type="text/jsx">
/**
* @jsx React.DOM
*/
var Profile = Backbone.Model.extend({
defaults : {
name : null,
gender : null,
picture : null
}
});
var profile = new Profile({
name : "Christopher Pitt",
gender : "male",
picture : "http://placekitten.com/200/200"
});
var CardComponent = React.createClass({
render : function() {
return (
<div className="card">
<div className="picture">
<img src={this.props.profile.get("picture")} />
</div>
<div className="name">
{this.props.profile.get("name")}
<small>
({this.props.profile.get("gender")})
</small>
</div>
</div>
);
}
});
React.renderComponent(
<CardComponent profile={profile} />,
document.body
);
</script>
</body>
</html>
在这个例子中,我们将这个Profile的实例作为prop传递给了CardComponent组件。然后,在render()
方法里面,我们使用get()
方法获取了模型中的数据。
一个复杂一些的例子
在上面的代码中,我们使用的数据都是静态的数据,但是在现实世界中,数据都是动态的。在下面的代码中,我们将使用非死不可的API来获取一些动态的数据,并将这些数据渲染到组件中。
下面的代码会涉及到一些Facebook接口的调用,如果你对这些调用方法不熟悉,完全没关系,你只需要将这些接口看做是一般的ajax方法即可,目的只是为了从远程服务器中获取我们想要的数据。
代码如下所示:
<!doctype html>
<html lang="en">
<head>
<script src="jquery-2.0.3/build/jquery.js"></script>
<script src="underscore-1.5.2/build/underscore.js"></script>
<script src="backbone-1.1.0/build/backbone.js"></script>
<script src="react-0.8.0/build/react.js"></script>
<script src="react-0.8.0/build/JSXTransformer.js"></script>
<style>
body {
padding : 20px;
font-family : helvetica, arial;
}
.picture {
margin : 10px 0;
}
</style>
</head>
<body>
<button class="connect">Connect</button>
<div class="target"></div>
<div id="fb-root"></div>
<script type="text/jsx">
/**
* @jsx React.DOM
*/
var Profile = Backbone.Model.extend({
defaults : {
name : null,
gender : null,
picture : null
}
});
var CardComponent = React.createClass({
componentWillMount : function() {
profile.on("change", (function() {
this.forceUpdate();
}.bind(this)));
},
componentWillUnmount : function() {
profile.off("change");
},
render : function() {
return (
<div className="card">
<div className="picture">
<img src={this.props.profile.get("picture")} />
</div>
<div className="name">
{this.props.profile.get("name")}
<small>
({this.props.profile.get("gender")})
</small>
</div>
</div>
);
}
});
var connect = document.querySelector(".connect");
var target = document.querySelector(".target");
var profile = new Profile();
var fetchProfile = function() {
React.renderComponent(
<CardComponent profile={profile} />,
target
);
FB.api("/me", "get", {}, function(result) {
profile.set("name", result.name);
profile.set("gender", result.gender);
});
var params = "?redirect=false&width=200&height=200";
FB.api(
"/me/picture" + params,
"get",
{},
function(result) {
profile.set("picture", result.data.url);
}
);
};
var login = function() {
FB.login(function() {
fetchProfile();
});
};
window.fbAsyncInit = function() {
FB.init({
appId : "579585842125092",
status : true,
xfbml : true
});
connect.addEventListener("click", function() {
login();
});
FB.Event.subscribe(
"auth.authResponseChange",
function(response) {
if (response.status === "connected") {
fetchProfile();
}
}
);
};
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, "script", "facebook-jssdk"));
</script>
</body>
</html>
简单来说,排除掉那些复杂的API部分,我们需要做的事情仅仅是在profile中的数据发生变化时调用forceUpdate()
方法。一般来说,只有在模型的state发生变化时,组件会自动去进行diff,然后重新render。但是由于我们将profile以prop的方式添加到了组件中,因此需要通过使用forceUpdate()
方法去手动重新渲染组件。
总结
React是一个非常酷的UI库,但是它只是库,而不是框架。因此我们可以将React和其他的框架进行结合,作为框架中View部分的有力补充。在本文中,我们初步学习了如何将React和Backbone的Model部分结合起来使用,希望本文能对正在学习React的你有所帮助。
本文参考自React + Backbone Model,原文地址https://medium.com/react-tutorials/react-backbone-model-8aaec65a546c