Backbone模型整合React(React + Backbone Model)

模型非常有效的组织接口数据。Backbone的模型,特别是在通过绑定各种事件当数据发生变化时重新渲染界面。

使用Backbone

我们已经介绍了如何引入Backbone依赖,但还是熟悉一下如何使用模型把,通常是这样的:

<!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>

这个例子so easy。我们通过继承Backbone.Model,给模型定义一些默认值。然后我们通过提供键值对实例化模型。
取值可以使用get()这个方法。我们使用这个方法的原因是不能直接访问(不是直接访问这个值)。JS目前是没有get/set方法的,可以使用Backbone来实现这两个方法,使用这个方法我们就可以监听change事件并根据我们的需要调整界面。

渲染模型

让我们创建一个叫Profile的模型

<!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模型传递给CardComponent组件。然后在render方法中我们使用getter填充组件。

填充模型

这个例子中使用的是静态数据,但如果我们想用动态真是的数据该怎么办呢?让我们连接Facebook并配置我们的数据把!
访问https://developers.facebook.com并选择Apps->Create a New App。取个名字,一个命名空间和一个分类并点击Create App

记录好App ID,当我们在示例应用中需要整合Facebook需要它。我们需要添加localhost到允许域名中。做好这些,我们点击Add Platform并选择Website,输入http://localhost/这是站点URL并添加localhostApp Domains字段中,点击Save按钮就可以继续了!

让我们看看如何将Facebook SDK嵌入到代码中,像下面一样:

<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    FB.init({
      appId  : '{your-app-id}',
      status : true,
      xfbml  : true
    });
  };

  (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>

确保将{your-app-id}替换成你创建Fackbone app时的App ID,否则JS就会报错。

由于我们在Fackbone中添加了localhost,我们接下来需要在本地添加一个Web服务器来运行代码,运行下面命令:

python -m SimpleHTTPServer

这将启动一个Web服务器,你可以在浏览器中输入http://localhost:8000 来访问。
最后,让我们来看看加了Facebook的用了React的Backbone模型怎么样:

<!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>

让我们看看里面怎么回事:

  1. 我们像Quickstart引导的一样载入Facebook JS SDK。添加fb-root元素,window.fbAsyncInit这个方法初始化程序。
  2. 在执行FB.init()这个方法,我们添加了两种事件:绑定点击事件在.connect按钮上和authResponseChange事件在FB对象上。如果用户没有验证时点击按钮进入登陆流程。当他们验证通过authResponseChange时间将触发并执行fetchProfile这个方法。
  3. fetchProfile这个方法将CardComponent组件渲染在.target元素上。这个时候一个空的Card被渲染,立即触发两个渲染方法:遍历会员信息资料和会员照片。这些反应是由于model的字段变化触发了forceUpdate()这个方法。

结论

我们已经成功整合Backbone模型、React和Facebook SDK了。模型让我们非常有效的管理数据,反过来更新我们的React组件,这在集合中一样有效…

翻译自:https://medium.com/react-tutorials/react-backbone-model-8aaec65a546c#.ywf9zhqk6

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值