Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

One pattern and two variants added #24

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 87 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,10 @@ be defined as a separate template from the list itself.

### Solution

You can pass the template function for the partial as a parameter to the first
You can pass the template function for the partial as a parameter to the first
template.

In this example, the function `itemTemplate` is passed onto the parameters for
In this example, the function `itemTemplate` is passed onto the parameters for
`template()`.

``` javascript
Expand Down Expand Up @@ -577,6 +577,91 @@ App.ChromeView = Backbone.View.extend({

[pep8]: http://www.python.org/dev/peps/pep-0008/

### Variation: closure-scoped sub/delegate views

In addition to making the instance of a sub or delegate view "private" by prepending an underscore to the variable name, you can also make the view definition, instance, or both private by scoping it within a closure with the parent view.

``` javascript
(function() {
var TabView = Backbone.View.extend(/* ... */); // TabView is not accessible outside the closure
var tabs = new TabView; // tabs is not accessible outside the closure
App.ChromeView = Backbone.View.extend({
render: function() {
tabView.setElement(this.el);
}
});
})();
```

Variation originally described at [Egeste.NET][egeste_closure_scope]

[egeste_closure_scope]: http://egeste.net/blog/2012/10/20/backbone-pattern-closure-scoped-sub-views/

Update chaining
---------------

__The problem:__ How do you render a view to present all the information in its model, and only update specific elements as the model’s attributes change so that you don't have to completely re-render the view every time the model changes?

__The solution:__ Create an update function for every model attribute you're going to present in the view, and have it return the view so it can be chained with other update functions.

``` javascript
App.ChromeView = Backbone.View.extend({
initialize: function() {
this.model
.on('change:foo', this.updateFoo, this)
.on('change:bar', this.updateBar, this)
},
render: function() {
this.$el.html(/* ... */)
this.$('input.foo').datepicker(/* ... */)
return this
.updateFoo()
.updateBar()
},
updateFoo: function() {
this.$('input.foo').val(this.model.get('foo'))
return this
},
updateBar: function() {
this.$('.bar').text(this.model.get('bar'))
return this
}
})
```

Pattern originally described at [Egeste.NET][egeste_update_chaining]

[egeste_update_chaining]: http://egeste.net/blog/2012/10/24/backbone-pattern-chain-able-update-functions/

### Variation: chaining updates within updates for attributes with relationships to other attributes

In the event that a model attribute changes that has implications for some other portion of the view, or possibly some relationship with another model attribute, you can chain the updates within each other. For example, if foo changing means that something in bar’s update function should execute, simply have foo execute & return the updateBar function.

``` javascript
App.ChromeView = Backbone.View.extend({
initialize: function() {
this.model
.on('change:foo', this.updateFoo, this)
.on('change:bar', this.updateBar, this)
},
render: function() {
this.$el.html(/* ... */)
this.$('input.foo').datepicker(/* ... */)
return this.updateFoo()
},
updateFoo: function() {
this.$('input.foo').val(this.model.get('foo'))
return this.updateBar()
},
updateBar: function() {
this.$('.bar').text(this.model.get('bar'))
return this
}
})
```

Variation originally described at [Egeste.NET][egeste_update_chaining]

General patterns
================

Expand Down