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:28] – [Render View] eechriseg-259:ch15 [2013/03/05 20:44] (current) – [Complete CRUD App (in-memory storage)] eechris
Line 270: Line 270:
 </code> </code>
  
-[[http://jsfiddle.net/cpjobling/pFhdh/1/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/01-view-01/index.html|01-view-01]]+[[http://jsfiddle.net/cpjobling/pFhdh/1/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/03-view-01/index.html|03-view-01]]
  
 ---- ----
Line 289: Line 289:
 </code> </code>
  
-[[http://jsfiddle.net/cpjobling/pFhdh/8/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/01-view-02/index.html|01-view-02]]+[[http://jsfiddle.net/cpjobling/pFhdh/8/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/03-view-02/index.html|03-view-02]]
  
 ---- ----
Line 295: Line 295:
 Render is a function that is used to build the DOM that represents the HTML in the view. Note ''$el'' is the jQuery representation of the views element ''el'' (which by default is a div). Render is a function that is used to build the DOM that represents the HTML in the view. Note ''$el'' is the jQuery representation of the views element ''el'' (which by default is a div).
  
-===== Initialize View =====+===== Initialize View at Startup =====
  
 <code javascript> <code javascript>
-initialize: function () { +$(document).ready(function () { 
-  this.$el.empty(); +    projectApp = new HomeView(); 
-  this.render(); +});
-},+
 </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/6/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/03-view-04/index.html|03-view-04]]
  
 ---- ----
  
-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 call the view, defined as in the previous slide, on the ''$(document).ready'' event that we saw in the session on jQuery
-===== Define Model =====+===== Adding View Automatically =====
  
 <code javascript> <code javascript>
-(function ($) {+function ($) { 
 +    HomeView = Backbone.View.extend({ 
 +        el: 'body',
  
-    Project = Backbone.Model.extend({});+        initialize: function ({...},
  
-    firstProject = new Project({ +        render: function ({...}
-        title: 'Project 1'+
     });     });
- 
 })(jQuery); })(jQuery);
 +$(document).ready(function () {
 +    projectApp = new HomeView();
 +});
 </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://jsfiddle.net/cpjobling/pFhdh/9/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/03-view-05/index.html|03-view-05]]
  
-===== Define Model =====+----
  
-<code javascript> +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 browser. By 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"''. 
-(function ($) {+===== Multiple Views =====
  
-    Project = Backbone.Model.extend({});+<code javascript> 
 +    HomeView = Backbone.View.extend({...});
  
-    firstProject new Project({ +    ListView Backbone.View.extend({ 
-        title: 'Project 1'+        tagName: 'ul'
 +        initialize: function () {...}, 
 +        render: function () { 
 +            this.$el.empty(); 
 +            this.$el.append("<li>Hello</li>"); 
 +            this.$el.append("<li>Goodbye</li>"); 
 +            return this; 
 +        }
     });     });
- 
-})(jQuery); 
 </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://jsfiddle.net/cpjobling/pFhdh/11/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/03-view-06/index.html|03-view-06]]
  
-===== Define Model =====+---- 
 + 
 +Here, we add a ''ListView'', based on an unordered-list, for the display of list items. 
 +===== Views can render other views =====
  
 <code javascript> <code javascript>
-(function ($) {+    HomeView = Backbone.View.extend(
 +        el: 'body', 
 +        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>
  
-    Project = Backbone.Model.extend({});+[[http://jsfiddle.net/cpjobling/pFhdh/12/|jsFiddle]] - [[http://localhost:4567/backbonejs-hands-on/code/03-view-07/index.html|03-view-07]]
  
-    firstProject = new Project({ +----
-        title: 'Project 1' +
-    });+
  
-})(jQuery);+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 ===== 
 + 
 +  * 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''
 + 
 +---- 
 + 
 +A brief list would include: 
 +  * Moustache 
 +  * Handlebars 
 +  * Jade 
 +  * EJS 
 + 
 +Use Google to find out more. 
 + 
 +===== A Simple Template ===== 
 + 
 +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>  
 + 
 +---- 
 + 
 +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! 
 + 
 +===== Rendering a Template ===== 
 + 
 +<code javascript> 
 +ListView = Backbone.View.extend({ 
 + : 
 + initialize: function () { 
 +   this.template = _.template($('#item-container').html()); 
 + }
 + 
 + render: function (
 +    this.$el.empty(); 
 +    this.$el.append("<li>Hello</li>"); 
 +    : 
 +    this.$el.append(this.template({value: "Hello Backbone"})); 
 +    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]] 
  
-===== Define Model =====+ 
 +[[http://localhost:4567/backbonejs-hands-on/code/04-template-01/index.html|04-template-01]] 
 +---- 
 + 
 +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]] 
 + 
 +===== 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>
  
-})(jQuery);+---- 
 + 
 +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> 
 +$(document).ready(function () { 
 +    projectApp = new AppRouter(); 
 +    Backbone.history.start(); 
 +});
 </code> </code>
  
-[[http://jsfiddle.net/cpjobling/HHw5j/2/|jsFiddle]] [[http://localhost:4567/backbonejs-hands-on/code/01-model-10/index.html|01-model-01]]+---- 
 + 
 +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. 
 + 
 +===== Events ===== 
 + 
 +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. 
 + 
 +===== Views Listening to Events ===== 
 + 
 +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. 
 + 
  
-===== Application Router =====  
-===== Events =====  
 ===== Complete CRUD App (in-memory storage) =====  ===== Complete CRUD App (in-memory storage) ===== 
 +
 +  * 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
 +
 +[[http://localhost:4567/backbonejs-hands-on/app/index.html|app/index.html]]
 ===== Summary of this Session ===== ===== Summary of this Session =====
  
Line 402: 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.1362511739.txt.gz · Last modified: 2013/03/05 19:28 by eechris