Browse files

fix 0.6 example

  • Loading branch information...
1 parent 8603096 commit 1fa5f0a449d26388d7a9619429d5c602af17875c @tbranyen committed Aug 15, 2012
Showing with 60 additions and 10 deletions.
  1. +18 −7 backbone.layoutmanager.js
  2. +1 −1 dist/backbone.layoutmanager.min.js
  3. +0 −2 examples/0.6/swap-layout.html
  4. +1 −0 test/vendor/backbone.js
  5. +40 −0 test/views.js
View
25 backbone.layoutmanager.js
@@ -249,7 +249,7 @@ var LayoutManager = Backbone.View.extend({
// Return the deferred.
return this.__manager__.renderDeferred;
}
-
+
// Wait until this View has rendered before dealing with nested Views.
this._render(LayoutManager._viewRender).fetch.then(function() {
// Disable the ability for any new sub-views to be added.
@@ -314,6 +314,8 @@ var LayoutManager = Backbone.View.extend({
if (root.__manager__.handler) {
root.__manager__.handler.resolveWith(root, [root.el]);
+
+ // Remove the handler, so it's never accidentally referenced.
delete root.__manager__.handler;
}
@@ -322,10 +324,10 @@ var LayoutManager = Backbone.View.extend({
// is also triggered.
if (_.isFunction(root.__manager__.callback)) {
root.__manager__.callback.call(root, root.el);
- }
- // Remove the most recent callback.
- delete root.__manager__.callback;
+ // Remove the most recent callback.
+ delete root.__manager__.callback;
+ }
// Remove the rendered deferred.
delete root.__manager__.renderDeferred;
@@ -494,10 +496,15 @@ var LayoutManager = Backbone.View.extend({
// Configure a View to work with the LayoutManager plugin.
setupView: function(view, options) {
- var views;
+ var views, viewOptions;
var proto = Backbone.LayoutManager.prototype;
var viewOverrides = _.pick(view, keys);
+ // If the View has already been setup, no need to do it again.
+ if (view.__manager__) {
+ return;
+ }
+
// Ensure necessary properties are set.
_.defaults(view, {
// Ensure a view always has a views object.
@@ -518,6 +525,10 @@ var LayoutManager = Backbone.View.extend({
options = view.options = _.defaults(options || {}, view.options,
proto.options);
+ // Ensure view events are properly copied over.
+ viewOptions = _.pick(options, ["events"].concat(_.values(options.events)));
+ _.extend(view, viewOptions);
+
// If the View still has the Backbone.View#render method, remove it. Don't
// want it accidentally overriding the LM render.
delete viewOverrides.render;
@@ -599,8 +610,8 @@ var LayoutManager = Backbone.View.extend({
// options.
views = options.views || view.views;
- // Set the internal views.
- if (views) {
+ // Set the internal views, only if selectors have been provided.
+ if (_.keys(views).length) {
view.setViews(views);
}
View
2 dist/backbone.layoutmanager.min.js
@@ -3,4 +3,4 @@
* Copyright 2012, Tim Branyen (@tbranyen)
* backbone.layoutmanager.js may be freely distributed under the MIT license.
*/
-(function(a){"use strict";var b,c=a.Backbone,d=a._,e=a.$,f=c.View.prototype._configure,g=c.View.prototype.render,h=c.View.extend({constructor:function(a){a=a||{},h.setupView(this,a),c.View.call(this,a),this.__manager__.prefix=this._options().paths.layout||""},swapLayout:function(a){return a.views=d.defaults({},this.views,a.views),a.setElement(this.el),a},insertView:function(a,b){return b?this.setView(a,b,!0):this.setView(a,!0)},insertViews:function(a){return d.each(a,function(b,c){a[c]=[].concat(b)}),this.setViews(a)},getView:function(a){return this.getViews(a).first().value()},getViews:function(a){var b=d.chain(this.views).map(function(a){return[].concat(a)},this).flatten().value();return d.chain(d.filter(b,a?a:d.identity))},setView:function(a,b,c){var e,f,g=this;return d.isString(a)||(c=b,b=a,a=""),this.views=this.views||{},!c&&this.views[a]&&(d.isArray(this.views[a])?d.each(this.views[a],function(a){a.remove()}):this.views[a].remove()),f=b._options(),b.__manager__||h.setupView(b,f),b.render=function(e){function j(){(!c||!b.__manager__.hasRendered)&&f.partial(g.el,a,b.el,c)&&(b.__manager__.hasRendered=!0),b.delegateEvents(),b.__manager__.handler&&(b.__manager__.handler.resolveWith(b,[b.el]),delete b.__manager__.handler),i.resolveWith(b,[b.el]),d.isFunction(e)&&e.call(b,b.el)}var i=f.deferred();return b._removeView(),h.prototype.render.call(b).then(j),i.promise()},!b.__manager__.prefix&&f.paths&&(b.__manager__.prefix=f.paths.template||""),b.__manager__.parent=this,b.__manager__.selector=a,c?(e=this.views[a]=this.views[a]||[],d.isArray(this.views[a])||(e=this.views[a]=[this.views[a]]),d.indexOf(e,b)>-1?b:(e.push(b),b.__manager__.append=!0,b)):this.views[a]=b},setViews:function(a){return d.each(a,function(a,b){if(d.isArray(a))return d.each(a,function(a){this.insertView(b,a)},this);this.setView(b,a)},this),this},render:function(a){var b=this,c=this._options(),e=c.deferred();return this.__manager__.renderDeferred?(this.__manager__.callback=a,this.__manager__.renderDeferred):(this._render(h._viewRender).fetch.then(function(){b.__manager__.renderDeferred=e;var a=d.map(b.views,function(a){function e(a,b){if(!a.length)return b();var c=a.shift();c.render(function(){e(a,b)})}var b;return d.isArray(a)?(b=c.deferred(),e(d.clone(a),function(){b.resolve()}),b.promise()):a.render()});c.when(a).then(function(){e.resolveWith(b,[b.el])})}),e.then(function(){d.isFunction(a)&&a.call(b,b.el),b.__manager__.handler&&(b.__manager__.handler.resolveWith(b,[b.el]),delete b.__manager__.handler),d.isFunction(b.__manager__.callback)&&b.__manager__.callback.call(b,b.el),delete b.__manager__.callback,delete b.__manager__.renderDeferred}))},remove:function(){return h.cleanViews(this),this._remove.apply(this,arguments)},_options:function(){return d.extend({},this,h.prototype.options,this.options)}},{_cache:{},_makeAsync:function(a,b){var c=a.deferred();return c.async=function(){return c._isAsync=!0,b},c},_viewRender:function(a){function g(c,d){h.cache(b,d),d&&f.html(a.el,f.render(d,c)),e.fetch.resolveWith(a,[a.el])}var b,c,e,f=a._options();return{render:function(i){var j=a.template||f.template;return a.serialize&&(f.serialize=a.serialize),!i&&d.isFunction(f.serialize)?i=f.serialize.call(a):!i&&d.isObject(f.serialize)&&(i=f.serialize),e=h._makeAsync(f,d.bind(g,a,i)),e.fetch=f.deferred(),a.__manager__.handler=e,d.isString(j)&&(b=a.__manager__.prefix+j),(c=h.cache(b))?(g(i,c,b),e):(d.isString(j)?c=f.fetch.call(e,a.__manager__.prefix+j):j!=null&&(c=f.fetch.call(e,j)),e._isAsync||g(i,c),e)}}},cleanViews:function(a){d.each([].concat(a),function(a){a.unbind(),a.views&&d.each(a.views,function(a){h.cleanViews(a)}),d.isFunction(a.cleanup)&&a.cleanup.call(a)})},cache:function(a,b){if(a in this._cache)return this._cache[a];if(a!=null&&b!=null)return this._cache[a]=b},configure:function(a){d.extend(h.prototype.options,a),a.manage&&(c.View.prototype.manage=!0)},setupView:function(a,e){var f,g=c.LayoutManager.prototype,i=d.pick(a,b);d.defaults(a,{views:{},__manager__:{},_options:h.prototype._options,_removeView:h._removeView}),e=a.options=d.defaults(e||{},a.options,g.options),delete i.render,d.extend(e,i),a._remove=c.View.prototype.remove,a._render=function(a){var b,c=this._options().beforeRender,e=this._options().afterRender;return d.isFunction(c)&&c.call(this,this),this.trigger("beforeRender",this),b=a(this).render(),b.then(function(){var a=this.__manager__.parent,b=this,c=function(){this.delegateEvents(),d.isFunction(e)&&e.call(this,this),this.trigger("afterRender",this)};if(!a||!a.__manager__.handler)return c.call(this);a.__manager__.handler.then(function(){c.call(b)})}),b},a.render=h.prototype.render,a.remove!==g.remove&&(a._remove=a.remove,a.remove=g.remove),a.__manager__.prefix="",f=e.views||a.views,f&&a.setViews(f),a.template&&(e.template=a.template,delete a.template)},_removeView:function(a){a=a||this,a.getViews().each(function(a){var b=a.__manager__,c=d.isBoolean(a.keep)?a.keep:a.options.keep;if(!c&&a.__manager__.append===!0){a.remove();if(d.isArray(b.parent.views[b.selector]))return b.parent.getView(function(a,c){a.__manager__.selector===b.selector&&b.parent.views[b.selector].splice(c,1)});delete b.parent[b.selector]}})}});d.each(["get","set","insert"],function(a){var b=c.View.prototype,d=h.prototype;b[a+"View"]=d[a+"View"],b[a+"Views"]=d[a+"Views"]}),c.Layout=c.LayoutManager=h,c.LayoutView=c.View.extend({manage:!0}),c.View.prototype._configure=function(){var a=f.apply(this,arguments);return this.manage&&h.setupView(this),a},h.prototype.options={paths:{},deferred:function(){return e.Deferred()},fetch:function(a){return d.template(e(a).html())},partial:function(a,b,c,d){var f=b?e(a).find(b):e(a);return f.length?(this[d?"append":"html"](f,c),!0):!1},html:function(a,b){e(a).html(b)},append:function(a,b){e(a).append(b)},when:function(a){return e.when.apply(null,a)},render:function(a,b){return a(b)}},b=d.keys(h.prototype.options)})(this);
+(function(a){"use strict";var b,c=a.Backbone,d=a._,e=a.$,f=c.View.prototype._configure,g=c.View.prototype.render,h=c.View.extend({constructor:function(a){a=a||{},h.setupView(this,a),c.View.call(this,a),this.__manager__.prefix=this._options().paths.layout||""},swapLayout:function(a){return a.views=d.defaults({},this.views,a.views),a.setElement(this.el),a},insertView:function(a,b){return b?this.setView(a,b,!0):this.setView(a,!0)},insertViews:function(a){return d.each(a,function(b,c){a[c]=[].concat(b)}),this.setViews(a)},getView:function(a){return this.getViews(a).first().value()},getViews:function(a){var b=d.chain(this.views).map(function(a){return[].concat(a)},this).flatten().value();return d.chain(d.filter(b,a?a:d.identity))},setView:function(a,b,c){var e,f,g=this;return d.isString(a)||(c=b,b=a,a=""),this.views=this.views||{},!c&&this.views[a]&&(d.isArray(this.views[a])?d.each(this.views[a],function(a){a.remove()}):this.views[a].remove()),f=b._options(),b.__manager__||h.setupView(b,f),b.render=function(e){function j(){(!c||!b.__manager__.hasRendered)&&f.partial(g.el,a,b.el,c)&&(b.__manager__.hasRendered=!0),b.delegateEvents(),b.__manager__.handler&&(b.__manager__.handler.resolveWith(b,[b.el]),delete b.__manager__.handler),i.resolveWith(b,[b.el]),d.isFunction(e)&&e.call(b,b.el)}var i=f.deferred();return b._removeView(),h.prototype.render.call(b).then(j),i.promise()},!b.__manager__.prefix&&f.paths&&(b.__manager__.prefix=f.paths.template||""),b.__manager__.parent=this,b.__manager__.selector=a,c?(e=this.views[a]=this.views[a]||[],d.isArray(this.views[a])||(e=this.views[a]=[this.views[a]]),d.indexOf(e,b)>-1?b:(e.push(b),b.__manager__.append=!0,b)):this.views[a]=b},setViews:function(a){return d.each(a,function(a,b){if(d.isArray(a))return d.each(a,function(a){this.insertView(b,a)},this);this.setView(b,a)},this),this},render:function(a){var b=this,c=this._options(),e=c.deferred();return this.__manager__.renderDeferred?(this.__manager__.callback=a,this.__manager__.renderDeferred):(this._render(h._viewRender).fetch.then(function(){b.__manager__.renderDeferred=e;var a=d.map(b.views,function(a){function e(a,b){if(!a.length)return b();var c=a.shift();c.render(function(){e(a,b)})}var b;return d.isArray(a)?(b=c.deferred(),e(d.clone(a),function(){b.resolve()}),b.promise()):a.render()});c.when(a).then(function(){e.resolveWith(b,[b.el])})}),e.then(function(){d.isFunction(a)&&a.call(b,b.el),b.__manager__.handler&&(b.__manager__.handler.resolveWith(b,[b.el]),delete b.__manager__.handler),d.isFunction(b.__manager__.callback)&&(b.__manager__.callback.call(b,b.el),delete b.__manager__.callback),delete b.__manager__.renderDeferred}))},remove:function(){return h.cleanViews(this),this._remove.apply(this,arguments)},_options:function(){return d.extend({},this,h.prototype.options,this.options)}},{_cache:{},_makeAsync:function(a,b){var c=a.deferred();return c.async=function(){return c._isAsync=!0,b},c},_viewRender:function(a){function g(c,d){h.cache(b,d),d&&f.html(a.el,f.render(d,c)),e.fetch.resolveWith(a,[a.el])}var b,c,e,f=a._options();return{render:function(i){var j=a.template||f.template;return a.serialize&&(f.serialize=a.serialize),!i&&d.isFunction(f.serialize)?i=f.serialize.call(a):!i&&d.isObject(f.serialize)&&(i=f.serialize),e=h._makeAsync(f,d.bind(g,a,i)),e.fetch=f.deferred(),a.__manager__.handler=e,d.isString(j)&&(b=a.__manager__.prefix+j),(c=h.cache(b))?(g(i,c,b),e):(d.isString(j)?c=f.fetch.call(e,a.__manager__.prefix+j):j!=null&&(c=f.fetch.call(e,j)),e._isAsync||g(i,c),e)}}},cleanViews:function(a){d.each([].concat(a),function(a){a.unbind(),a.views&&d.each(a.views,function(a){h.cleanViews(a)}),d.isFunction(a.cleanup)&&a.cleanup.call(a)})},cache:function(a,b){if(a in this._cache)return this._cache[a];if(a!=null&&b!=null)return this._cache[a]=b},configure:function(a){d.extend(h.prototype.options,a),a.manage&&(c.View.prototype.manage=!0)},setupView:function(a,e){var f,g,i=c.LayoutManager.prototype,j=d.pick(a,b);if(a.__manager__)return;d.defaults(a,{views:{},__manager__:{},_options:h.prototype._options,_removeView:h._removeView}),e=a.options=d.defaults(e||{},a.options,i.options),g=d.pick(e,["events"].concat(d.values(e.events))),d.extend(a,g),delete j.render,d.extend(e,j),a._remove=c.View.prototype.remove,a._render=function(a){var b,c=this._options().beforeRender,e=this._options().afterRender;return d.isFunction(c)&&c.call(this,this),this.trigger("beforeRender",this),b=a(this).render(),b.then(function(){var a=this.__manager__.parent,b=this,c=function(){this.delegateEvents(),d.isFunction(e)&&e.call(this,this),this.trigger("afterRender",this)};if(!a||!a.__manager__.handler)return c.call(this);a.__manager__.handler.then(function(){c.call(b)})}),b},a.render=h.prototype.render,a.remove!==i.remove&&(a._remove=a.remove,a.remove=i.remove),a.__manager__.prefix="",f=e.views||a.views,d.keys(f).length&&a.setViews(f),a.template&&(e.template=a.template,delete a.template)},_removeView:function(a){a=a||this,a.getViews().each(function(a){var b=a.__manager__,c=d.isBoolean(a.keep)?a.keep:a.options.keep;if(!c&&a.__manager__.append===!0){a.remove();if(d.isArray(b.parent.views[b.selector]))return b.parent.getView(function(a,c){a.__manager__.selector===b.selector&&b.parent.views[b.selector].splice(c,1)});delete b.parent[b.selector]}})}});d.each(["get","set","insert"],function(a){var b=c.View.prototype,d=h.prototype;b[a+"View"]=d[a+"View"],b[a+"Views"]=d[a+"Views"]}),c.Layout=c.LayoutManager=h,c.LayoutView=c.View.extend({manage:!0}),c.View.prototype._configure=function(){var a=f.apply(this,arguments);return this.manage&&h.setupView(this),a},h.prototype.options={paths:{},deferred:function(){return e.Deferred()},fetch:function(a){return d.template(e(a).html())},partial:function(a,b,c,d){var f=b?e(a).find(b):e(a);return f.length?(this[d?"append":"html"](f,c),!0):!1},html:function(a,b){e(a).html(b)},append:function(a,b){e(a).append(b)},when:function(a){return e.when.apply(null,a)},render:function(a,b){return a(b)}},b=d.keys(h.prototype.options)})(this);
View
2 examples/0.6/swap-layout.html
@@ -57,7 +57,6 @@
},
swap: function(ev) {
- console.log("woot");
this.swapLayout(goodbye).render();
}
});
@@ -71,7 +70,6 @@
},
swap: function(ev) {
- console.log("here");
this.swapLayout(hello).render();
}
});
View
1 test/vendor/backbone.js
@@ -1224,6 +1224,7 @@
delegateEvents: function(events) {
if (!(events || (events = getValue(this, 'events')))) return;
this.undelegateEvents();
+
for (var key in events) {
var method = events[key];
if (!_.isFunction(method)) method = this[events[key]];
View
40 test/views.js
@@ -991,3 +991,43 @@ test("render works when assigned early", 1, function() {
ok(hit, "render works as expected when assigned early");
});
+
+test("Render doesn't work inside insertView", 1, function() {
+ var V = Backbone.LayoutView.extend({
+ template: "<p class='inner'><%= lol %></p>",
+ fetch: function(path) { return _.template(path); }
+ });
+
+ var n = new Backbone.LayoutView({
+ template: "<p></p>",
+ fetch: function(path) { return _.template(path); }
+ });
+
+ n.render();
+ n.insertView("p", new V({ serialize: { lol: "hi" } })).render();
+
+ equal(n.$("p.inner").html(), "hi", "Render works with insertView");
+});
+
+// https://github.com/tbranyen/backbone.layoutmanager/issues/134
+test("Ensure events are copied over properly", 1, function() {
+ var hit = false;
+ var layout = new Backbone.Layout({
+ template: "<p></p>",
+ fetch: function(path) { return _.template(path); },
+
+ events: {
+ "click p": "test"
+ },
+
+ test: function(ev) {
+ hit = true;
+ }
+ });
+
+ layout.render();
+
+ layout.$("p").click();
+
+ ok(hit, "Events were bound and triggered correctly");
+});

0 comments on commit 1fa5f0a

Please sign in to comment.