walmartlabs/thorax — pull request #92 by eastridge (2013-01-09 21:55:46+00:00)
Title: More context

Note that this PR is not code complete, but I wanted to put the proposed API out in the open now for discussion.

Presently the template context is not distinct from the view object, and `this` + `this.model.attributes` is the default context. This pull request adds a built in `_context` model to `Throax.View` that controls what context is passed to rendered templates. By default any key arbitrarily added to a view will *not* be available in the template.

Adds the following methods to `Thorax.View`:

- `get(key)`
- `set(key, value, options) set(attrs, options)`
- `unset(key)`

`options` may contain data object options that would previously be passed to `setModel` and `setCollection`. The following methods are removed:

- `setModel`
- `setCollection`
- `bindDataObject`
- `unbindDataObject`

`bindDataObject` / `unbindDataObject` are now automatic as we can detect what objects are passed via `set`. `setModel` / `setCollection` can be replaced with: `set('model', model)`. The constructor signature has changed. Though not widely used, previously any attribute set in the constructor would become available on the instance:

var view = new Thorax.View({
template: '{{key}}',
key: 'value'
});

view.template === '{{key}}';
view.key === 'value';

The constructor will now pass the first argument to set, so the above code above could be represented as:

var view = new (Thorax.View.extend({
template: '{{key}}'
}))({key: 'value'});

view.template === '{{key}}';
view.key === undefined
view.get('key') === 'value';

or

var view = new (Thorax.View.extend({
template: '{{key}}'
}));
view.set({key: 'value'});

view.template === '{{key}}';
view.key === undefined
view.get('key') === 'value';

Data objects (models, collections and views) passed to `set` will be copied over to the view, but other values will not:

view.set({
model: model,
key: 'value'
});
view.model === model;
view.key === undefined
view.get('key') === 'value';

Also added for more fine grained control is a `merge` option for models. It defaults to true for a model set at the key `model`, and false for other models. If true it sets the models attributes directly in the context, if false it sets

var model = new Thorax.Model({key: 'value'}),
otherModel = new Thorax.Model({otherKey: 'value'});
view.set('model', model, {merge: true});
view.set('otherModel', otherModel, {merge: false});

// in template:
// {{key}}{{otherModel.otherKey}}

The `context` method is still available to control the final context passed to a template.

After this PR is discussed & merged or rejected, I'd like to finish up the activate / deactivate discussion then mark the library as 2.0.0rc1. Any other API changes or alternate context proposals should be raised now.