how to use ractive as view component in backbone.j

2019-07-23 04:12发布

问题:

I am new to ractive.js and want to integrate it with backbone.js. I found a backbone adapter for ractive howevere didn't found a sample which will show to use it effectively. Need a sample that explain how to use ractive.js as a view component in backbone.js

回答1:

Since the official demo seems to be down, I was able to put together a simple demo based on the rest of documentation.

Basically include ractive and ractive adapter for backbone after backbone and dependencies, then in your view's render method initialize a new ractive view passing it the backbone view's element, template and model data as el, template and data respectively as shown in below example.

For one way bindings, use the model getter method like {{model.get('prop')}} and for two way bindings directly refer the property like {{model.attributes.name}}

Also, to avoid possibility of memory leak, override backbone view's remove method and have it destroy it's ractive view before removing itself.

Hope the comment explains the process:

// Nothing special, create a model instance with data
var model = new Backbone.Model({
  name: "John"
});

// Backbone view constructor
var View = Backbone.View.extend({
  template: $('#ractiveTest').html(),
  initialize: function() {
    this.render();
  },
  events: {
    'click button': 'remove'
  },
  render: function() {
    //initialize ractive view as part of rendering
    this.ractive = new Ractive({
      el: this.el, // pass the view's element to ractive
      template: this.template, // pass the view's template to ractive
      data: {
        user: this.model // pass view's model data to ractive
      }
    });
  },
  //override view's remove method to destroy ractive instance as well
  remove: function() {
    // Just for added safety
    this.ractive.teardown();
    Backbone.View.prototype.remove.call(this);
  }
});

// initialize the view and pass in the model.
var view = new View({
  model: model
});

// append the view to DOM
view.$el.appendTo(document.body);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.1/backbone.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ractive/0.7.3/ractive.js"></script>
<script src="//cdn.jsdelivr.net/ractive.adaptors-backbone/latest/ractive-adaptors-backbone.min.js"></script>
<script type="text/template" id="ractiveTest">
  <label>
    Enter your name:
    <input value="{{user.attributes.name}}">
  </label>
  <p>Hello, {{user.get('name')}}!</p>
  <button>remove</button>
</script>

I find it a bit strange that we have to do user.get('name') in the template for one way binding and user.attributes.name for two way binding.

It could've been abstracted away in the Backbone adapter likeuser.name likes rivets does.