User Tools

Site Tools


eg-259:ch15

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
eg-259:ch15 [2013/03/05 19:32] – [Initialize View] eechriseg-259:ch15 [2013/03/05 20:44] (current) – [Complete CRUD App (in-memory storage)] eechris
Line 308: Line 308:
  
 Here we call the view, defined as in the previous slide, on the ''$(document).ready'' event that we saw in the session on jQuery. Here we call the view, defined as in the previous slide, on the ''$(document).ready'' event that we saw in the session on jQuery.
-===== Initialize View =====+===== Adding View Automatically =====
  
 <code javascript> <code javascript>
-initialize: function () { +function ($) { 
-  this.$el.empty(); +    HomeView = Backbone.View.extend({ 
-  this.render(); +        el: 'body', 
-},+ 
 +        initialize: function () {...}, 
 + 
 +        render: function () {...} 
 +    }); 
 +})(jQuery); 
 +$(document).ready(function () { 
 +    projectApp = new HomeView(); 
 +});
 </code> </code>
  
-[[http://jsfiddle.net/cpjobling/pFhdh/7/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/03-view-03/index.html|03-view-03]]+[[http://jsfiddle.net/cpjobling/pFhdh/9/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/03-view-05/index.html|03-view-05]]
  
 ---- ----
  
-The ''initialize'' method is called once when a new view is instantiatedHere it empties the div and then calls the ''render'' function. +By defining the ''el'' property to be the //body// element, the elements contained in the view will automatically be added to the document when it is loaded in the browserBy making the rendered DOM elements the result of processing an HTML template, quite complex user interface components can be built-up from smaller parts. Note that the el property will often be set to a div with an id, as in ''el: "#contents"''
- +===== Multiple Views =====
-===== Initialize View =====+
  
 <code javascript> <code javascript>
-initialize: function () { +    HomeView = Backbone.View.extend({...}); 
-  this.$el.empty(); + 
-  this.render(); +    ListView = Backbone.View.extend({ 
-},+        tagName: 'ul', 
 +        initialize: function () {...}, 
 +        render: function () { 
 +            this.$el.empty(); 
 +            this.$el.append("<li>Hello</li>"); 
 +            this.$el.append("<li>Goodbye</li>"); 
 +            return this; 
 +        } 
 +    });
 </code> </code>
  
-[[http://jsfiddle.net/cpjobling/pFhdh/7/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/03-view-03/index.html|03-view-03]]+[[http://jsfiddle.net/cpjobling/pFhdh/11/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/03-view-06/index.html|03-view-06]]
  
 ---- ----
  
-The ''initialize'' method is called once when a new view is instantiated. Here it empties the div and then calls the ''render'' function. +Here, we add a ''ListView'', based on an unordered-list, for the display of list items
- +===== Views can render other views =====
-===== Initialize View =====+
  
 <code javascript> <code javascript>
-initialize: function () { +    HomeView = Backbone.View.extend({ 
-  this.$el.empty(); +        el: 'body', 
-  this.render(); +        initialize: function () { 
-},+            this.render(); 
 +        }, 
 +        render: function () { 
 +            this.$el.empty(); 
 +            this.$el.append("<h1>My Project App</h1>"); 
 +            this.listView = new ListView(); 
 +            this.$el.append(this.listView.render().el); 
 +            return this; 
 +        } 
 +    });
 </code> </code>
  
-[[http://jsfiddle.net/cpjobling/pFhdh/7/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/03-view-03/index.html|03-view-03]]+[[http://jsfiddle.net/cpjobling/pFhdh/12/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/03-view-07/index.html|03-view-07]]
  
 ---- ----
  
-The ''initialize'' method is called once when a new view is instantiated. Here it empties the div and then calls the ''render'' function.+Here the home view has been extended and is being used to render the list view inside its own render method. You could render a whole tree of HTML elements in the same way. 
 +===== Templates =====
  
-===== Initialize View =====+  * Templates extend the power of views by allowing arbitrary pieces of HTML to be stored and rendered at run time by the interpolation of simple fragments of JavaScript. 
 +  * There are several JavaScript templating libraries and Backbone is agnostic about which is used. 
 +  * The default in Backbone is underscore template: ''_.template''.
  
-<code javascript> +---- 
-initializefunction () { + 
-  this.$el.empty(); +A brief list would include
-  this.render(); +  * Moustache 
-}, +  * Handlebars 
-</code>+  * Jade 
 +  * EJS 
 + 
 +Use Google to find out more
 + 
 +===== A Simple Template =====
  
-[[http://jsfiddle.net/cpjobling/pFhdh/7/|jsFiddle]] [[http://localhost:4567/backbonejs-hands-on/code/03-view-03/index.html|03-view-03]]+In the HTML: 
 +<code html> 
 +<!-- undescore template ... compiles body then interpolates value at call time --> 
 +<script type="text/template" id="item-container"> 
 +  <li><%= value %></li> 
 +</script> 
 +</code
  
 ---- ----
  
-The ''initialize'' method is called once when a new view is instantiatedHere it empties the div and then calls the ''render'' function.+Here we use a script with type of ''text/template''The browser will ignore this, as the script is not JavaScript, but the browser will still build a script DOM element and Backbone can retrieve its content later by grabbing the content of the ''$(#item-container')'' element. Ember.js has a very similar approach, albeit with a different templating engine.
  
 +The template syntax is very simple: anything between ''<%= ... %>'' is considered to be an expression to be output. The content can be any JavaScript statement that returns a value. Another tag pair ''<% ... %>'' can be used to encapsulate any JavaScript code, e.g. a loop, that doesn't output a value. Te syntax is very similar to the syntax used in server-side templating languages like PHP!
  
-===== Define Model =====+===== Rendering a Template =====
  
 <code javascript> <code javascript>
-(function ($) {+ListView = Backbone.View.extend(
 + : 
 + initialize: function () { 
 +   this.template = _.template($('#item-container').html()); 
 + },
  
-    Project = Backbone.Model.extend({});+ render: function () { 
 +    this.$el.empty(); 
 +    this.$el.append("<li>Hello</li>"); 
 +    : 
 +    this.$el.append(this.template({value: "Hello Backbone"})); 
 +    return this; 
 + } 
 +}); 
 +</code>
  
-    firstProject = new Project({ 
-        title: 'Project 1' 
-    }); 
  
-})(jQuery); 
-</code> 
  
-[[http://jsfiddle.net/cpjobling/HHw5j/2/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/01-model-10/index.html|01-model-01]]+[[http://localhost:4567/backbonejs-hands-on/code/04-template-01/index.html|04-template-01]] 
 +----
  
-===== Define Model =====+Here the HTML from the script tag with id ''item-container'' is passed to the template function 
 +''_.template'' where it is "compiled" into a DOM object witha place-holder for a //value//. Later, when the render function appends the template to the DOM, the value is passed as an argument to the template and it will then be output into the document. 
 + 
 +This simple idea is remarkably powerful and is used in many popular server- and client-side web development frameworks. 
 + 
 +===== A Second Example =====
  
 <code javascript> <code javascript>
-(function ($) {+        render: function () { 
 +            var el = this.$el, 
 +                template = this.template;
  
-    Project = Backbone.Model.extend({});+            el.empty();
  
-    firstProject = new Project({ +            projects.each(function (project) 
-        title: 'Project 1' +                el.append(template(project.toJSON())); 
-    });+            });
  
-})(jQuery);+            return this; 
 +        }
 </code> </code>
  
-[[http://jsfiddle.net/cpjobling/HHw5j/2/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/01-model-10/index.html|01-model-01]]+[[http://localhost:4567/backbonejs-hands-on/code/04-template-02/index.html|04-template-02]] 
 +----
  
-===== Define Model =====+Here we use a similar template, this time outputting HTML view prepresenting each project in the collection.
  
-<code javascript> 
-(function ($) { 
  
-    Project Backbone.Model.extend({});+===== Router =====
  
-    firstProject = new Project({ +Here we have a more complex example using three templates: 
-        title: 'Project 1' +  * One for the Project list 
-    });+  * One for the project detail -- including a form for editing the title of the selected project 
 +  * One to render the list items themselves. 
 +Here is the code
 +[[http://localhost:4567/backbonejs-hands-on/code/05-router-01/index.html|05-router-01]]
  
-})(jQuery);+===== App Router ===== 
 + 
 +<code javascript> 
 +    AppRouter = Backbone.Router.extend({ 
 +        routes: { 
 +            "": "home", 
 +            "add": "add", 
 +            "close": "home", 
 +        }
 +        home: function (
 +            console.log('home'); 
 +            new HomeView(); 
 +        }, 
 +        add: function () { 
 +            console.log('add'); 
 +            new AddView(); 
 +        } 
 +    });
 </code> </code>
  
-[[http://jsfiddle.net/cpjobling/HHw5j/2/|jsFiddle]] [[http://localhost:4567/backbonejs-hands-on/code/01-model-10/index.html|01-model-01]]+----
  
-===== Define Model =====+The purpose of the router is to define some "URL"s that the client will use to navigate around the application. These are simply strings that map a URL to a method. In this example, they map the client-side URLs ''#'', ''#add'' and ''#close'' to the methods ''home'', ''add'' and ''home'' respectively. These methods in turn will create, dynamically, a //home view// and an //add view// which will respectively display the list of projects and allow a project to be added. 
 + 
 +===== Router Initialisation =====
  
 <code javascript> <code javascript>
-(function ($) {+$(document).ready(function () { 
 +    projectApp = new AppRouter(); 
 +    Backbone.history.start(); 
 +}); 
 +</code>
  
-    Project = Backbone.Model.extend({});+----
  
-    firstProject = new Project({ +Here we create a new object representing the whole application as an ''AppRouter'', which itself is defined as an instance of ''Backbone.Router''. We also call ''Backbone.history.start();'' which enables the browser to record the client-side state as URLs that can be retrieved as bookmarks or using the back button.
-        title: 'Project 1' +
-    });+
  
-})(jQuery); +===== Events =====
-</code>+
  
-[[http://jsfiddle.net/cpjobling/HHw5j/2/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/01-model-10/index.html|01-model-01]]+In the second router example [[http://localhost:4567/backbonejs-hands-on/code/05-router-02/index.html|05-router-02]] we add two event listeners to the ''AddView'' so that both the //add// button and pressing //enter// in the text field will cause an event that will trigger the invocation of the ''add'' method that will eventually cause a new project to be added to the collection.
  
-===== Define Model =====+===== Views Listening to Events =====
  
-<code javascript> +In the final iteration [[http://localhost:4567/backbonejs-hands-on/code/05-router-03/index.html|05-router-03]], we add the new project to the project collection and also register an event listener on the ''ListView'' so that when a new project is added, a change event is fired and the whole list is redrawn.
-(function ($) {+
  
-    Project = Backbone.Model.extend({}); 
  
-    firstProject = new Project({ 
-        title: 'Project 1' 
-    }); 
  
-})(jQuery)+===== Complete CRUD App (in-memory storage===== 
-</code>+
  
-[[http://jsfiddle.net/cpjobling/HHw5j/2/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/01-model-10/index.html|01-model-01]]+  * This final version of the app includes a facility for showing existing projects and allowing their titles to be edited. 
 +  * The app now has an ''UpdateView'' which supports the editing feature and the list items now include an id in the URL that allows a particular project to be selected for editing. 
 +  * It overrides the ''Backbone.sync'' object to allow data to be read from an array of objects in memory rather than a RESTful api (which is it's default behaviour). 
 +  * View the code for insight into how this works
  
-===== Application Router =====  +[[http://localhost:4567/backbonejs-hands-on/app/index.html|app/index.html]]
-===== Events =====  +
-===== Complete CRUD App (in-memory storage) ===== +
 ===== Summary of this Session ===== ===== Summary of this Session =====
  
Line 462: Line 533:
   * [[eg-259:ch15#Events|Events]]   * [[eg-259:ch15#Events|Events]]
   * [[eg-259:ch15#Complete CRUD App (in-memory storage)|Complete CRUD App (in-memory storage)]]   * [[eg-259:ch15#Complete CRUD App (in-memory storage)|Complete CRUD App (in-memory storage)]]
-===== Homework Exercises ===== 
  
-  - Come up with something 
  
  
eg-259/ch15.1362511968.txt.gz · Last modified: 2013/03/05 19:32 by eechris