kjantzer-backbone-subviews

0.7.0 • Public • Published

Backbone.js Subviews

Version 0.7.0

Extends Backbone.View with support for nested subviews that can be reused and cleaned up when need be. (helps mitigate ghosted views)

Features

  • Cleanup views when no longer needed
  • Provided access to parent views
  • Add additional methods to help with reusing Views
  • Keeps views uninitialized until needed
  • Propagates model to subviews
  • Listen to models/collections by defining them in a hash
  • And more...

Using Subviews

var MySubview = Backbone.View.extend({
    
    render: function(){
        console.log(this.parentView.className) // 'my-view'
        console.log(this.viewName) // 'my-subview'
    },
    
    cleanup: function(){
        console.log('perform cleanup')
        // such as this.stopListening(this.model)
    }
});
 
var MyView = Backbone.View.extend({
    
    className: 'my-view',
     
    initialize: function(){
        this.sv('my-subview', MySubview).renderTo(this)
    },
    
    render: function(){
    
        // render the child view
        this.sv('my-subview').render();
    
        return this;
    }
})

When you remove a view, all subviews will be informed and told to cleanup

MyView.remove() // MySubview:'perform cleanup'

You can reuse views too instead of recreating over and over.

var MyListSubivew = Backbone.View.extend({});
 
var MyListView = Backbone.View.extend({
    
    render: function(){
    
        this.$el.html('')
        // assuming this view has a collection...
        this.collection.each(this.addOne, this)
    
        return this;
    },
    
    addOne: function(model){
        
        let viewName = 'item-'+model.id
        
        // MyListSubivew will only be initialized once for the given viewName
        this.sv(viewName, MyListSubivew)
            .setModel(model)
            .renderTo(this)
        
        // if you data/options are needed upon initialization of the view, you can do This
        // this.sv(viewName, MyListSubivew, {model: model, another:'option'})
    }
})

Defining Views

Since creating and appending subviews to a view is a common routine, backbone.subviews provides a way to setup and render them automatically for you.

var View1 = Backbone.View.extend({className: 'v1'});
var View2 = Backbone.View.extend({className: 'v2'});
var BadgeView = Backbone.View.extend({className: 'badge'});
var ViewColl = Backbone.View.extend({className: 'v-coll', tagName: 'ul'});
 
var RootView = Backbone.View.extend({
 
    className: 'rootview',
    template: '<h1 class="title">Title</h1>',
 
    views: {
        'view1': View1,
        'view2': View2,
        'badge': {
            view: BadgeView,
            appendTo: '.title'
        },
        'view-collection': {
            view: ViewColl,
            setModel: function(v, model){
                v.collection = model.get('a-child-collection')
            }
        }
    }
 
});

When the RootView is rendered, all the views defined in views will be initialized, appended to RootView and then their render() method called.

This will give us the following DOM structure

<div class="rootview">
    <h1 class="title">Title<div class="badge"></div></h1>
    <div class="v1"></div>
    <div class="v2"></div>
    <ul class="v-coll"></ul>
</div>

If you override render you'll need to remember to call renderViews() on your own.

Attaching Listeners to Model/Collections

It is common practice for a view to listen to a model or collection for changes and react accordingly. This can be done by specifying a hash of events like so:

listeners: {
    model: {
        'change': 'render',
        'destroy': 'remove',
        'reset': function(){
            // inline function also supported
        }
    },
    collection: {},
    'name-of-child-collection': {}
}
 
// the above is the equivalent of doing this manually
this.listenTo(this.model, 'change', this.render)
this.listenTo(this.model, 'destroy', this.remove)
this.listenTo(this.model, 'rest', function(){})

You'll notice above that Child Collection is supported. The third listener would evaluate to:

this.model.get('name-of-child-collection')

Methods & References

There are some useful methods added to Backbone.Views

.sv() or .subview() - save and access subviews

.renderTo() - render and append to a backbone view (or jquery element)

.empty() - clears the view of contents

.inDOM() - whether or not the view is presented in the DOM or just stored in memory

.reRender() - will only render if in the DOM

.renderViews() - init and append (if needed) and then render all defined views (this.views)

.forEachView(callback) - perform an action on all defined views

.renderTemplate() - will take this.template and merge with this.model and append to el. (See backbone.template-data)

.parentView - a reference to the parent view of this child

.parent(viewName, returnPromise=false) - will traverse up parent views until matched view name. Use root to get the top level view. Dot notation is supported for traversing up to a parent and then down to a subview.

.viewName - the name the child is stored under in the parent

Changelog

v0.7.0

  • Defined views:{} will get setModel called upon initialization (if they have it)
  • Model/Collection listeners can be defined and applied automatically

v0.6.2

  • collection: this.collection also passed to view upon creation (previously only this.model was given)

v0.6.1

  • fix .sv alias not passing opts arg

v0.6.0

  • return this in setModel for chainability
  • add renderTo method
  • view arg in .sv() can be uninitialized - the view will only initialize once.
  • defined view in views has setModel option available

v0.5.0

  • new .parent(viewName, returnPromise=false) method for traversing up the parent views to the one matching the given name

v0.4.0

  • add support for defining and automating subviews on a view

License

MIT © Kevin Jantzer - Blackstone Publishing

Readme

Keywords

none

Package Sidebar

Install

npm i kjantzer-backbone-subviews

Weekly Downloads

1

Version

0.7.0

License

MIT

Unpacked Size

16.3 kB

Total Files

4

Last publish

Collaborators

  • kjantzer