使用react来增强backbone视图功能

曾经用backbone做了几个项目,对它里面的视图功能真是不敢恭维,基本上用它作为前端mvc框架的都是为了兼容性,不过随着M$xp的放弃,以及win7未来的不支持,IE8已经成了不少公司兼容IE的底限了,所以这时候假如还用Backbone的话,确实有点对不起住自己,不过有些时候不是你想用什么就用什么的,所以这时候你就要想办法去提高backbone视图功能,这时候该是react出马的时候了,

React概览

react首先它是一个ui框架,用来创建独立的前端UI组件用的,类似于angularjs里的指令以及polymer里的web组件,为什么说它能够提高backbone视图功能,答案就在于它的独立性以及数据同步功能,类似于ng里的数据双向绑定,react基于state也提供了类似的数据跟视图的同步功能.

react提供了一个叫做JSX语法的UI输写规范,相当于在js里直接写html,而且不用包装成字符串,相当于js模板语言的结合体,所以这个在运行的时候是需要转换成真实可调用的js的,先看个例子

  • 带JSX语法的代码
/** @jsx React.DOM */
var component = React.createClass({
  render: function() {
    return <a href="http://venmo.com">Venmo</a>
  }
});
  • 转换后的代码
/** @jsx React.DOM */
var component = React.createClass({
  render: function() {
    return React.DOM.a( {href:"http://venmo.com"}, "Venmo")
  }
});

而且在前端构建里去整合这些转换工具也是非常方便的,目前已经有下面的npm模块:

  • require-jsx,这是一个RequireJS插件用来加载.jsx后缀文件的.

  • reactify,这是一个用在Browserify构建时候的jsx转换模块.

  • grunt-react,这是一个用在grunt构建时的一个grunt插件.

不过JSX语法是可选的,本身提供了React.DOM对象来支持各种html元素的构建,对react不熟悉的话,可以看这个教程

渲染React组件到Backbone视图中

我们先创建一个简单的组件,功能就是单击里面的链接然后去触发定义的一个方法,代码如下:

var MyWidget = React.createClass({
  handleClick: function() {
    alert('Hello!');
  },
  render: function() {
    return (
      <a href="#" onClick={this.handleClick}>Do something!</a>
    );
  }
});

然后我们添加一个backbone视图来渲染它.

var MyView = Backbone.View.extend({
  el: 'body',
  template: '<div class="widget-container"></div>',
  render: function() {
    this.$el.html(this.template);
    React.renderComponent(new MyWidget(), this.$('.widget-container').get(0));
    return this;
  }
});

new MyView().render();

下面是jsfiddle上面运行的例子,可以点击里面的链接看看效果.

React组件与Backbone通信

上面的例子只是单方面的调用,这里说下双方的交互,这才是实际项目中出现的场景.下面演示一个,在react组件里单击,然后在backbone视图里增加一个元素。

先定义一个react组件

var MyWidget = React.createClass({
  render: function() {
    return (
      <a href="#" onClick={this.props.handleClick}>Do something!</a>
    );
  }
});

注意这里的this.props是用来获取元素实例里的属性用的,然后我们来定义一个backbone视图

var MyView = Backbone.View.extend({
  el: 'body',
  template: '<div class="widget-container"></div>' +
            '<div class="outside-container"></div>',
  render: function() {
    this.$el.html(this.template);

    React.renderComponent(new MyWidget({
      handleClick: this.clickHandler.bind(this)
    }), this.$('.widget-container').get(0));

    return this;
  },
  clickHandler: function() {
    this.$(".outside-container").html("The link was clicked!");
  }
});

在上面的代码里通过new一个react组件,然后传递一个事件参数,利用bind方法把事件指向了视图实例中去,从而实现交互

来看看在jsfiddle上面的效果

通过上面的bind方法实现了react组件与backbone视图的交互,下面来看看backbone是怎么跟react交互的

Backbone与React组件通信

上面已经了解react组件与backbone视图的通信,这里讲下怎么利用backbone中的model与组件的通信,当model改变的时候怎么同步修改组件呢,下面我先定义一个简单的model

var ExampleModel = Backbone.Model.extend({
  defaults: {
    name: 'Backbone.View'
  }
});

然后我们定义两个视图,这里直接使用react组件来代替backbone里的视图,一个视图用来触发修改model,一个同步显示修改的model

// 这个视图用来同步显示修改的model属性
var DisplayView = React.createClass({
  componentDidMount: function() {
    this.props.model.on('change', function() {
      this.forceUpdate();
    }.bind(this));
  },

  render: function() {
    return (
      <p>
        {this.props.model.get('name')}
      </p>
    );
  }
});

下面的视图组件是用来触发model的修改

var ToggleView = React.createClass({
  handleClick: function() {
    this.props.model.set('name', 'React');
  },
  render: function() {
    return (
      <button onClick={this.handleClick}>
        model.set('name', 'React');
      </button>
    );
  }
});

最后我们来渲染这两组件,并传递model为这两件组件的属性

var model = new ExampleModel();

React.renderComponent((
  <div>
    <DisplayView model={model} />
    <ToggleView model={model} />
  </div>
), document.body);

注意下这里的this.forceUpdate方法,它是保证重新render组件用的,componentDidMount方法是组件初始化的时候会执行,这里负责绑定监听model改变事件的地方.

下面是在jsfiddle上面运行的效果,可以点击看看

总结

BackboneReact是一对极好的搭档,下面是一些其它关于这方面的blog,有兴趣的可以看看.

React官方也提供了一个与Backbone结合的Todo例子,an example Backbone+React TodoMVC app

虽然React阵营不是很成熟,但是它是一个令人兴奋的库,而且还可以投入生产环境,非常适合用来构建重用的组件,与Backbone的结合更是能够增强视图方面的业务能力.


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值