使用BackBone + React开发web应用 -- 使用Backbone的Model作为数据存储
发布在使用React.js开发web应用2014年12月9日view:6913
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

enter image description here

使用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

评论
发表评论
3年前
赞了此文章!
3年前
赞了此文章!
3年前
添加了一枚【评注】:这个效果好酷
3年前
添加了一枚【评注】:这个效果好酷
3年前
赞了此文章!
WRITTEN BY
张小俊128
Intern in Baidu mobile search department。认真工作,努力钻研,期待未来更多可能。
TA的新浪微博
PUBLISHED IN
使用React.js开发web应用

介绍React.js库使用的基础知识

我的收藏