Permalink
Browse files

changed how views are constructed, render is now the options.render o…

…verride, nesting of layouts
  • Loading branch information...
1 parent 211ff13 commit e7462057e524433b23490d2c395ee65cf679ea13 @tbranyen committed Jul 10, 2012
Showing with 172 additions and 53 deletions.
  1. +60 −53 backbone.layoutmanager.js
  2. +54 −0 examples/0.6/minimal.html
  3. +47 −0 examples/0.6/nested.html
  4. +11 −0 readme.md
View
@@ -1,5 +1,5 @@
/*!
- * backbone.layoutmanager.js v0.5.2
+ * backbone.layoutmanager.js v0.6
* Copyright 2012, Tim Branyen (@tbranyen)
* backbone.layoutmanager.js may be freely distributed under the MIT license.
*/
@@ -22,11 +22,6 @@ var LayoutManager = Backbone.View.extend({
constructor: function Layout(options) {
options = options || {};
- // Apply the default render scheme.
- this._render = function(manage) {
- return manage(this).render();
- };
-
// Ensure the View is setup correctly.
LayoutManager.setupView(this, options);
@@ -116,14 +111,6 @@ var LayoutManager = Backbone.View.extend({
// Set up the View.
LayoutManager.setupView(view, options);
- // If no render override was specified assign the default; if the render
- // is the fake function inserted, ensure that is updated as well.
- if (view.render.__fake__) {
- view._render = function(manage) {
- return manage(this).render();
- };
- }
-
// Custom template render function.
view.render = function(done) {
var viewDeferred = options.deferred();
@@ -326,6 +313,9 @@ var LayoutManager = Backbone.View.extend({
done.call(root, root.el);
}
+ // Resolve the View deferred.
+ root.__manager__.handler.resolveWith(root, [root]);
+
// Remove the rendered deferred.
delete root.__manager__.renderDeferred;
}).promise();
@@ -484,6 +474,11 @@ var LayoutManager = Backbone.View.extend({
// This static method allows for global configuration of LayoutManager.
configure: function(opts) {
_.extend(LayoutManager.prototype.options, opts);
+
+ // Allow LayoutManager to augment Backbone.View.prototype.
+ if (opts.augment) {
+ Backbone.View.prototype.augment = true;
+ }
},
// Configure a View to work with the LayoutManager plugin.
@@ -508,13 +503,38 @@ var LayoutManager = Backbone.View.extend({
// runtime and ensure they are available on the view object.
_.extend(options, _.pick(this, keys));
+ // Set the render if it is different from the Backbone.View.prototype.
+ if (view.render !== Backbone.View.prototype.render) {
+ options.render = view.render;
+ }
+
// By default the original Remove function is the Backbone.View one.
view._remove = Backbone.View.prototype.remove;
- // Reset the render function.
- if (!(view instanceof LayoutManager)) {
- view.options.render = LayoutManager.prototype.options.render;
- }
+ // Always use this render function when using LayoutManager.
+ view._render = function(manage) {
+ // If a beforeRender function is defined, call it.
+ if (_.isFunction(this.beforeRender)) {
+ this.beforeRender.call(this, this);
+ }
+
+ // Always emit a beforeRender event.
+ this.trigger("beforeRender", this);
+
+ // Render!
+ return manage(this).render().then(function() {
+ // If an afterRender function is defined, call it.
+ if (_.isFunction(this.afterRender)) {
+ this.afterRender.call(this, this);
+ }
+
+ // Always emit an afterRender event.
+ this.trigger("afterRender", this);
+ });
+ };
+
+ // Ensure the render is always set correctly.
+ view.render = LayoutManager.prototype.render;
// If the user provided their own remove override, use that instead of the
// default.
@@ -578,47 +598,34 @@ _.each(["get", "set", "insert"], function(method) {
backboneProto[method + "Views"] = layoutProto[method + "Views"];
});
-_.extend(Backbone.View.prototype, {
- // Add the ability to remove all Views.
- removeView: LayoutManager.removeView,
-
- // Add options into the prototype.
- _options: LayoutManager.prototype._options,
-
- // Override _configure to provide extra functionality that is necessary in
- // order for the render function reference to be bound during initialize.
- _configure: function() {
- var retVal = _configure.apply(this, arguments);
- var renderPlaceholder;
+// Convenience assignment to make creating Layout's slightly shorter.
+Backbone.Layout = Backbone.LayoutManager = LayoutManager;
+// A LayoutView is just a Backbone.View with augment set to true.
+Backbone.LayoutView = Backbone.View.extend({
+ augment: true
+});
- // Only update the render method for non-Layouts, which need them.
- if (!this.__manager__) {
- // Ensure the proper setup is made.
- this._render = this.options.render || this.render;
+// Override _configure to provide extra functionality that is necessary in
+// order for the render function reference to be bound during initialize.
+Backbone.View.prototype._configure = function() {
+ // Run the original _configure.
+ var retVal = _configure.apply(this, arguments);
- // Ensure render functions work as expected.
- renderPlaceholder = this.render = function() {
- if (this.render !== renderPlaceholder) {
- return this.render.apply(this, arguments);
- }
+ // If augment is set, do it!
+ if (this.augment) {
+ // Add the ability to remove all Views.
+ this.removeView = LayoutManager.removeView;
- // Call the render method.
- return this._render.apply(this, arguments);
- };
+ // Add options into the prototype.
+ this._options = LayoutManager.prototype._options;
- // Mark this function as fake for later checking and overriding in the
- // setView function.
- if (this._render === render) {
- this.render.__fake__ = true;
- }
- }
-
- return retVal;
+ // Set up this View.
+ LayoutManager.setupView(this, this._options());
}
-});
-// Convenience assignment to make creating Layout's slightly shorter.
-Backbone.Layout = Backbone.LayoutManager = LayoutManager;
+ // Act like nothing happened.
+ return retVal;
+};
// Default configuration options; designed to be overriden.
LayoutManager.prototype.options = {
View
@@ -0,0 +1,54 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+
+ <title>Allow augmenting</title>
+</head>
+<body>
+ <!-- Layout will be inserted here -->
+ <div class="main"></div>
+
+ <!-- Layout template -->
+ <script type="template" id="main">
+ <h1>Hello</h1>
+ <p></p>
+ </script>
+
+ <!-- Content template -->
+ <script type="template" id="content">
+ This is some content...
+ </script>
+
+ <!-- Required Library Dependencies -->
+ <script src="../../test/vendor/jquery.js"></script>
+ <script src="../../test/vendor/underscore.js"></script>
+ <script src="../../test/vendor/backbone.js"></script>
+ <script src="../../backbone.layoutmanager.js"></script>
+
+ <script>
+ Backbone.LayoutManager.configure({
+ augment: true
+ });
+
+ // Nested layouts
+ var View = Backbone.View.extend({
+ template: "#content",
+
+ render: function(template, context) {
+ return template(context);
+ },
+
+ afterRender: function() {
+ this.$el.appendTo(".main");
+ }
+ });
+
+ var view = new View();
+
+ view.render();
+
+ </script>
+</body>
+</html>
View
@@ -0,0 +1,47 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+
+ <title>Nested Layouts Example</title>
+</head>
+<body>
+ <!-- Layout will be inserted here -->
+ <div class="main"></div>
+
+ <!-- Layout template -->
+ <script type="template" id="main">
+ <h1>Hello</h1>
+ <p></p>
+ </script>
+
+ <!-- Required Library Dependencies -->
+ <script src="../../test/vendor/jquery.js"></script>
+ <script src="../../test/vendor/underscore.js"></script>
+ <script src="../../test/vendor/backbone.js"></script>
+ <script src="../../backbone.layoutmanager.js"></script>
+
+ <script>
+ // Nested layouts
+ var sub = Backbone.Layout({
+ template: "#main"
+ });
+
+ // Create a new Layout with a sub view for content.
+ var main = new Backbone.Layout({
+ template: "#main",
+
+ views: {
+ "p": sub
+ }
+ });
+
+ // Attach the Layout to the main container.
+ main.$el.appendTo(".main");
+
+ // Render the Layout
+ main.render();
+ </script>
+</body>
+</html>
View
@@ -36,6 +36,17 @@ included.
<script src="/js/backbone.layoutmanager.js"></script>
```
+If you are using RequireJS you can include using the shim configuration.
+
+``` javascript
+require.config({
+ shim: {
+ // Include layoutmanager and ensure Backbone is a loaded dependency.
+ "backbone.layoutmanager": ["backbone"]
+ }
+});
+```
+
## Usage ##
This example renders a View into a template which is injected into a layout.

0 comments on commit e746205

Please sign in to comment.