Skip to content

Commit

Permalink
Improve mixin of view ui hash to behaviors
Browse files Browse the repository at this point in the history
This commit makes the view ui hash available consistently in
Behaviors, making it available in callbacks as well as the
events and triggers hashes.  There is also some refactoring to simplify
and centralize how the views ui hash is mixed into the Behaviors
reducing duplication
  • Loading branch information
Ben McCormick authored and samccone committed Feb 23, 2015
1 parent 2d751ab commit 634f08b
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 12 deletions.
18 changes: 18 additions & 0 deletions docs/marionette.behavior.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,21 @@ Marionette.Behavior.extend({
}
});
```

### ui

Behaviors can have their own ui hash, which will be mixed into the ui hash of its associated view instance.
ui elements defined on either the behavior or the view will be made available within events, and triggers. They
also are attached directly to the behavior and can be accessed within behavior methods as `this.ui`.

```js
Marionette.Behavior.extend({
ui: {
'foo' : 'li.foo'
},

doStuff: function() {
this.ui.foo.trigger('something');
}
})
```
6 changes: 6 additions & 0 deletions src/behavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ Marionette.Behavior = Marionette.Object.extend({
this.view = view;
this.defaults = _.result(this, 'defaults') || {};
this.options = _.extend({}, this.defaults, options);
// Construct an internal UI hash using
// the views UI hash and then the behaviors UI hash.
// This allows the user to use UI hash elements
// defined in the parent view as well as those
// defined in the given behavior.
this.ui = _.extend({}, _.result(view, 'ui'), _.result(this, 'ui'));

Marionette.Object.apply(this, arguments);
},
Expand Down
18 changes: 6 additions & 12 deletions src/behaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,15 @@ Marionette.Behaviors = (function(Marionette, _) {

behaviorEvents: function(behaviorEvents, behaviors) {
var _behaviorsEvents = {};
var viewUI = this._uiBindings || _.result(this, 'ui');

_.each(behaviors, function(b, i) {
var _events = {};
var behaviorEvents = _.clone(_.result(b, 'events')) || {};
var behaviorUI = b._uiBindings || _.result(b, 'ui');

// Construct an internal UI hash first using
// the views UI hash and then the behaviors UI hash.
// This allows the user to use UI hash elements
// defined in the parent view as well as those
// defined in the given behavior.
var ui = _.extend({}, viewUI, behaviorUI);

// Normalize behavior events hash to allow
// a user to use the @ui. syntax.
behaviorEvents = Marionette.normalizeUIKeys(behaviorEvents, ui);
behaviorEvents = Marionette.normalizeUIKeys(behaviorEvents, getBehaviorsUI(b));

var j = 0;
_.each(behaviorEvents, function(behaviour, key) {
Expand Down Expand Up @@ -140,7 +132,6 @@ Marionette.Behaviors = (function(Marionette, _) {
// for views
function BehaviorTriggersBuilder(view, behaviors) {
this._view = view;
this._viewUI = _.result(view, 'ui');
this._behaviors = behaviors;
this._triggers = {};
}
Expand All @@ -154,10 +145,9 @@ Marionette.Behaviors = (function(Marionette, _) {

// Internal method to build all trigger handlers for a given behavior
_buildTriggerHandlersForBehavior: function(behavior, i) {
var ui = _.extend({}, this._viewUI, _.result(behavior, 'ui'));
var triggersHash = _.clone(_.result(behavior, 'triggers')) || {};

triggersHash = Marionette.normalizeUIKeys(triggersHash, ui);
triggersHash = Marionette.normalizeUIKeys(triggersHash, getBehaviorsUI(behavior));

_.each(triggersHash, _.bind(this._setHandlerForBehavior, this, behavior, i));
},
Expand All @@ -174,6 +164,10 @@ Marionette.Behaviors = (function(Marionette, _) {
}
});

function getBehaviorsUI(behavior) {
return behavior._uiBindings || behavior.ui;
}

return Behaviors;

})(Marionette, _);
11 changes: 11 additions & 0 deletions test/unit/behaviors.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,9 @@ describe('Behaviors', function() {
'click @ui.foo': 'onFooClick',
'click @ui.bar': 'onBarClick'
},

testViewUI: function() { this.ui.bar.trigger('test'); },
testBehaviorUI: function() { this.ui.foo.trigger('test'); },
onRender : this.onRenderStub,
onBeforeShow : this.onBeforeShowStub,
onShow : this.onShowStub,
Expand Down Expand Up @@ -344,6 +347,14 @@ describe('Behaviors', function() {
expect(this.onRenderStub).to.have.been.calledOnce;
});

it('should make the view\'s ui hash available to callbacks', function() {
expect(this.fooBehavior.testViewUI.bind(this.fooBehavior)).to.not.throw(Error);
});

it('should make the behavior\'s ui hash available to callbacks', function() {
expect(this.fooBehavior.testBehaviorUI.bind(this.fooBehavior)).to.not.throw(Error);
});

describe("the $el", function() {
beforeEach(function() {
this.view.$el.find('.foo').click();
Expand Down

0 comments on commit 634f08b

Please sign in to comment.