SlideShare uma empresa Scribd logo
1 de 116
Baixar para ler offline
•
•
•
var Comment = Backbone.Model.extend();
var Comment = Backbone.Model.extend();




var comment = new Comment({
    id: 83562107
    text: "       “   ”                  "
    created_at: "2011-07-03 09:04:34"
    user: {
        uid: "keso"
        id: "1000185"
        screen_name: "keso"
    }
});
•
•
•
– extend
- constructor / initialize
– get
– set
– escape
– has
– unset
– clear
– id
– cid
– attributes
– defaults
- toJSON
comment.get('text'); //       “    ”
                             comment.set(
                                {'text':'<script>alert('xss')</script>'},
                                {silent:true}
                                );


– extend                     comment.escape('text');
- constructor / initialize   // &lt;script&gt;alert(&#x27xss&#x27)
– get                        &lt;&#x2F;script&gt;
– set
– escape                     comment.has('city'); // false
– has
– unset                      comment.unset('text'); // trigger 'change' event
– clear
– id
– cid
– attributes
– defaults
- toJSON
comment.get('text'); //       “    ”
                             comment.set(
                                {'text':'<script>alert('xss')</script>'},
                                {silent:true}
                                );


– extend                     comment.escape('text');
- constructor / initialize   // &lt;script&gt;alert(&#x27xss&#x27)
– get                        &lt;&#x2F;script&gt;
– set
– escape                     comment.has('city'); // false
– has
– unset                      comment.unset('text'); // trigger 'change' event
– clear
– id
– cid
– attributes                 var Comment = new Backbone.Model.extend({
– defaults                       // hash or function()
- toJSON                         defaults: {
                                     'source': 'douban.com'
                                 },
                                 initialize: function() { ... }
                             });

                             var comment = new Comment();
                             comment.get('source'); // 'douban.com'
var Comment = new Backbone.Model.extend({
                             urlRoot: '/comments'
                             initialize: function(attrs) { ... }
                         });

                         var comment = new Comment({id:123456});
–   fetch                comment.url(); // '/comments/123456'
                         comment.fetch();
–   save
–   destroy
–   validate
–   url
–   urlRoot
                         var Comment = new Backbone.Model.extend({
–   parse
                             initialize: function(attrs) { ... },
–   clone
                             validate: function(attrs) {
–   isNew
                                 if ( attrs.text.length < 3 ) {
–   change
                                     return '             3     '
–   hasChanged
                                 }
–   changedAttributes
–   previous                 }
–   previousAttributes   });

                         var comment = new Comment();
                         comment.set({text:'ok'},{
                             error: function(model,error) {
                                 alert(error);
                             }
                         });
•
•
•
•
•
•
var Comments = new Backbone.Collection.extend({

      model: Comment,

      initialize: function(models,options) {

      }

});
[
    {
        text: "       “   ”                 "
        created_at: "2011-07-03 09:04:34"
        source: "douban.com"
        user: {
            city: "    "
            statuses_count: 172
            uid: "keso"
            following_count: 1688
            created_at: "2005-04-07 18:01:26"
            followers_count: 6178
            small_avatar: "http://img3.douban.com/icon/u1000185-2.jpg"
            id: "1000185"
            screen_name: "keso"
            ...
        }
        id: 83562107
    },
    {...}
    {...}
]
App.Collections.Comments = Backbone.Collection.extend({
–   model
–   constructor / initialize         model: Comment,
–   models
                                     initialize: function(models,options) {
–   toJSON
–   Underscore Methods (25)               this.url = '/api/statuses/' + options.id + '/comments'
–   get                                           + (options.count ? '?count=' + options.count : '')
–   getByCid                                      + (options.page ? '&page=' + options.page : '');
                                          this.page = 1;
–   at
–   length                           },
–   comparator
                                     comparator: function(model) {
–   sort
                                         return -model.get('id');
–   pluck                            }
–   url
–   parse
                               });
•
•
•
•
•
•
collection.create(attributes, [options])
collection.create(attributes, [options])



var Comments = new Comments([{...}]);
collection.create(attributes, [options])



var Comments = new Comments([{...}]);




Comments.create({text: "It's no big deal!"});
collection.create(attributes, [options])



var Comments = new Comments([{...}]);




Comments.create({text: "It's no big deal!"});
collection.create(attributes, [options])



var Comments = new Comments([{...}]);




Comments.create({text: "It's no big deal!"});




var comment = new Comment({
    text: "It's no big deal!",
});

comment.save();

Comments.add(comment);
•
•
•
App.Views.Comment = Backbone.View.extend({

      className: 'comment-item',

      template: $('#comment-item-template').html(),

      events: {
          "mouseenter"             : "showActions",
          "mouseleave"             : "hideActions"
      },

      initialize: function() {
          _.bindAll(this, 'render');
          this.model.bind('change', this.render);
      },

      render: function() {
          $(this.el).html(Mustache.to_html(this.template, this.model.toJSON()));
          $(this.el).attr({
              'data-item-id': this.model.id,
              'data-comment-id': this.model.id
          });
          return this;
      },

      showActions: function(e) {
          this.$('.icon-delete').show();
      },

      hideActions: function(e) {
          this.$('.icon-delete').hide();
      }
});
App.Views.Comment = Backbone.View.extend({

      className: 'comment-item',

      template: $('#comment-item-template').html(),

      events: {
          "mouseenter"             : "showActions",
          "mouseleave"             : "hideActions"
      },

      initialize: function() {
          _.bindAll(this, 'render');
          this.model.bind('change', this.render);
      },

      render: function() {
          $(this.el).html(Mustache.to_html(this.template, this.model.toJSON()));
          $(this.el).attr({
              'data-item-id': this.model.id,
              'data-comment-id': this.model.id
          });
          return this;
      },

      showActions: function(e) {
          this.$('.icon-delete').show();
      },
                                                                var view = new App.Views.Comment({
      hideActions: function(e) {                                    model: model
          this.$('.icon-delete').hide();
                                                                });
      }
});                                                             $('body').append(view.render().el);
App.Router.Shuo = Backbone.Router.extend({

      routes: {
          ""                                          :   "home",
          ":uid"                                      :   "profile",
          ":uid/following"                            :   "following",
          ":uid/status/:id"                           :   "permalink",
          "search/:query"                             :   "search"
      },

      initialize: function() {
          Backbone.history.start({pushState: true, root:'/'});
      },

      home: function() {
          App.Pages.Home = new App.Views.Home();
          oBody.append(App.Pages.Home.render().el);
          this.navigate('');
      },

      profile: function(uid) {
          App.Pages.Profile[uid] = new App.Views.Profile({uid: uid});
          oBody.append(App.Pages.Profile[uid].render().el);
          this.navigate(uid,true);
      },

      following: function(uid) { ...
      permalink: function(uid,id) { ...
      search: function(query) { ...
});
router.route(route, name, callback)




  initialize: function(options) {

      // Matches #page/10, passing "10"
      this.route("page/:number", "page", function(number){ ... });

      // Matches /117-a/b/c/open, passing "117-a/b/c"
      this.route(/^(.*?)/open$/, "open", function(id){ ... });

  }
•

•
Backbone.history.start([options])



  App.Router.Shuo = Backbone.Router.extend({

        routes: {
            ""                                       :   "home",
            ":uid"                                   :   "profile",
            ":uid/following"                         :   "following",
            ":uid/status/:id"                        :   "permalink",
            "search/:query"                          :   "search"
        },

        initialize: function() {
            Backbone.history.start({pushState: true, root:'/'});
        },
  ...
Backbone.Events

◦ "add" (model, collection) — when a model is added to a collection.

◦ "remove" (model, collection) — when a model is removed from a collection.

◦ "reset" (collection) — when the collection's entire contents have been replaced.

◦ "change" (model, collection) — when a model's attributes have changed.

◦ "change:[attribute]" (model, collection) — when a specific attribute has been updated.

◦ "destroy" (model, collection) — when a model is destroyed.

◦ "error" (model, collection) — when a model's validation fails, or a save call fails on the server.

◦ "route:[name]" (router) — when one of a router's routes has matched.

◦ "all" — this special event fires for any triggered event, passing the event name as the first
   argument.
object.bind(event, callback)


  App.Views.Comment = Backbone.View.extend({

        className: 'comment-item',

        template: $('#comment-item-template').html(),

        initialize: function() {
            _.bindAll(this, 'render');
            this.model.bind('change', this.render);
        },

        render: function() {
            $(this.el).html(Mustache.to_html(this.template, this.model.toJSON()));
            $(this.el).attr({
                'data-item-id': this.model.id,
                'data-comment-id': this.model.id
            });
            return this;
        }
  });
Backbone.sync is the function that Backbone calls every time it
attempts to read or save a model to the server. By default, it uses
(jQuery/Zepto).ajax to make a RESTful JSON request. You can
override it in order to use a different persistence strategy, such as
WebSockets, XML transport, or Local Storage.
Models
Interactive Data Domain-
    specific methods
Models               Collections
Interactive Data Domain-
                           Ordered Sets of Models
    specific methods
Models               Collections
Interactive Data Domain-
                           Ordered Sets of Models
    specific methods




       Views
 Render HTML/CSS With
 Javascript templating
Models               Collections
Interactive Data Domain-
                           Ordered Sets of Models
    specific methods




       Views                    Router
 Render HTML/CSS With      Methods For Routing URL
 Javascript templating            Fragments
Models               Collections
Interactive Data Domain-
                           Ordered Sets of Models
    specific methods




       Views                    Router
 Render HTML/CSS With      Methods For Routing URL
 Javascript templating            Fragments
Models               Collections
Interactive Data Domain-
                           Ordered Sets of Models
    specific methods




       Views                    Router
 Render HTML/CSS With      Methods For Routing URL
 Javascript templating            Fragments
public/js
public/js
public/js
-- /libs/
  |- jquery.js
  |- backbone.js
  |- underscore.js
  |- json2.js
  |- mustache.js
  |- cacheprovider.js

--   /applications.js
--   /models/
--   /collections/
--   /views/
--   /controllers/
../application.js
var App = {
         Views: {},
         Router: {},
         Collections: {},
         Cache: new CacheProvider(),
         initialize: function(){
                 new App.Router.Shuo();
                 Backbone.history.start({pushState: true});
         }
     };




public/js/application.js
App.Routers.Shuo = Backbone.Router.extend({

           routes: {
               ""                                  :   "home",
               "comments"                          :   "comments",
               "mentions"                          :   "mentions",
               ":uid"                              :   "profile",
               ":uid/following"                    :   "following",
               ":uid/followers"                    :   "followers",
               ":uid/status/:id"                   :   "permalink",
               "search/users/:query"               :   "user_search",
               "search/:query"                     :   "search"
           },

           initialize: function() { ... },

           home: function() { ... },

           comments: function() { ... },

           mentions: function() { ... },

           profile: function(uid) { ... },

           following: function(uid) { ... },

           followers: function(uid) { ... },

           permalink: function(uid,id) { ... },

           user_search: function(query) { ... },

           search: function(query) { ... }
     });



public/js/controllers/shuo.js
public/js/models
public/js/models
public/js/models
|-   comment.js
|-   comment_notification.js
|-   mention.js
|-   stat.js
|-   status.js
|-   user.js
public/js/collections
public/js/collections
public/js/collections
|-   comments.js
|-   follow_in_common.js
|-   followers.js
|-   home_timeline.js
|-   likers.js
|-   mentions.js
|-   resharers.js
|-   results.js
|-   suggestions.js
|-   user_recommendations.js
|-   user_results.js
|-   user_timeline.js
|-   users.js
public/js/views
Home
Main
Main   Dashboard
HomeHeader




  Stream
HomeHeader
             Navigation



             Following

             Followers




             Suggestion

  Stream

                ADs

               Footer
Status


Resharers




Comments
Status


Resharers




Comments
new App.Views.StreamItem();
            model: Status
 Status     model.fetch()
            this.render()




Resharers




Comments
new App.Views.StreamItem();
            model: Status
 Status     model.fetch()
            this.render()




Resharers   new App.Views.Resharers()...




Comments
new App.Views.StreamItem();
            model: Status
 Status     model.fetch()
            this.render()




Resharers   new App.Views.Resharers()...




            new App.Views.Comments()

            this.collection = new Comments([],{
                id: status.id

Comments    });

            this.collection.fetch()
            this.collection.create()
            this.collection.remove()
...
     <div id="page-outer">
     </div>
     ...



    <script id="status-item-template" type="text/template">...</script>
    <script id="comment-item-template" type="text/template">...</script>
    ...




template/app.html
App.Views.Permalink = Backbone.View.extend({
        el: oDoc,
        initialize: function(options) {
            _.bindAll(this, 'render', 'loadStatus', 'loadResharers', 'loadLikers', 'loadComments');
            var self = this;
            $.ajax('/api/statuses/' + options.id + '?pack=1&comment_count=50&reshare_count=14&like_count=14')
                .success(function(resp) {
                    self.status = new Status(resp.status, {id: options.id});
                    self.comments = new App.Collections.Comments(resp.comments, {id: options.id});
                    self.resharers = new App.Collections.Resharers(resp.reshare_users, {id: options.id});
                    self.loadStatus();
                })
                .error(function(resp){
                    // 404
                    }
                });
        },
        render: function() {
            return this;
        },
        loadStatus: function() {
            var view = new App.Views.StreamItem({
                model: this.status
            });
            this.loadComments();
            this.loadResharers();
            oPageContainer.prepend(view.render().el);
        },
        loadResharers: function() { ... },
        loadComments: function() { ... }
    });




public/js/views/permalink.js
App.Views.Permalink = Backbone.View.extend({
       ...
       loadComments: function() {
           var view = new App.Views.Comments({
               model: this.status,
               collection: this.comments
           });
           oPageContainer.prepend(view.render().el);
       }
   });




public/js/views/permalink.js
App.Views.Comments = Backbone.View.extend({

                     className: 'comments-manager',

                     template: $('#comments-components-template').html(),
                     title_template: '{{#comments_count}}<h3>{{comments_count}}    </h3>{{/comments_count}}',

                     events: {
                         "click    .submit"            : "submitComment",
                     },

                     initialize: function(options) {

                          _.bindAll(this,'render', 'loadTitle', 'loadOne', 'loadAll');
                          this.status = options.status;
                          this.collection.bind('add', this.loadOne);
                          this.collection.bind('remove', this.loadAll);
                          this.collection.bind('reset', this.loadAll);
                     },

                     render: function() {
                         $(this.el).html(Mustache.to_html(this.template,{ logged_out: !shuo.loggedIn }));

                          this.title = this.$('.comments-title');
                          this.oBnSubmit = this.$('.submit-area input');
                          this.comments = this.$('.comments-items');

                          this.loadTitle(this.status.toJSON());
                          this.loadAll();
                          return this;
                     },

                     loadOne: function(model) {
                         if ( model.isNew() ) {
                             var view = new App.Views.Comment({
                                 model: model
                             });
                             this.comments.append(view.render().el);
                         }
                     },

                     loadTitle: function(data) {
                         this.title.html(Mustache.to_html(this.title_template,data));
                     },

                     loadAll: function() {
public/js/views/comments.js
                     },
                         this.collection.each(this.loadOne);

                     create: function(e) {
App.initialize();
BackboneJS
MustacheJS
UnderscoreJS
BackboneJS
MustacheJS
UnderscoreJS
MustacheJS
{
    entities: {
        user_mentions: [],
        urls: []
    }
    text: "       “   ”                 "
    created_at: "2011-07-03 09:04:34"
    source: "douban.com"
    user: {
        city: "    "
        icon_avatar: "http://img3.douban.com/icon/ui1000185-2.jpg"
        statuses_count: 172
        uid: "keso"
        following_count: 1688
        url: ""
        created_at: "2005-04-07 18:01:26"
        description: "keso                                            http://
blog.donews.com/keso"
        followers_count: 6178
        location: "   "
        small_avatar: "http://img3.douban.com/icon/u1000185-2.jpg"
        following: false
        verified: false
        large_avatar: "http://img3.douban.com/icon/ul1000185-2.jpg"
        id: "1000185"
        screen_name: "keso"
    }
    id: 83562107
}
<script id="comment-item-template" type="text/template">
    <div class="comment-item-content" data-user-id="{{#user}}{{uid}}{{/user}}" data-item-id="{{id}}" data-
comment-id="{{id}}">
        {{#user}}
        <div class="icon">
            <a href="/#{{uid}}"><img src="{{small_avatar}}" alt="{{screen_name}}"/></a>
        </div>
        {{/user}}
        <div class="content">
            <p>
                 {{#user}}
                 <a href="/#!/{{uid}}" class="to" title="{{uid}}">{{screen_name}}</a>
                 {{/user}}
                 <span class="comment-time">{{timestamp}}</span>
            </p>
            <p>
                 <span class="comment-text">{{{text}}}</span>
                 <a href="" class="icon-comment" title="   "><img src="http://img3.douban.com/anduin/pics/
blank.gif"/></a>
            </p>
        </div>
    </div>
</script>
Mustache.to_html(template,data);
MustacheJS
BackboneJS
MustacheJS

UnderscoreJS
UnderscoreJS
http://shuo.douban.com/imdonkey

Mais conteúdo relacionado

Mais procurados

Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Konstantin Kudryashov
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
Functionality Focused Code Organization
Functionality Focused Code OrganizationFunctionality Focused Code Organization
Functionality Focused Code OrganizationRebecca Murphey
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery ApplicationsRebecca Murphey
 
Sencha Touch - Introduction
Sencha Touch - IntroductionSencha Touch - Introduction
Sencha Touch - IntroductionABC-GROEP.BE
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End DevsRebecca Murphey
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patternsSamuel ROZE
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitRebecca Murphey
 
Backbone js
Backbone jsBackbone js
Backbone jsrstankov
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDAleix Vergés
 
Building mobile web apps with Mobello
Building mobile web apps with MobelloBuilding mobile web apps with Mobello
Building mobile web apps with MobelloJeong-Geun Kim
 
Keeping It Small with Slim
Keeping It Small with SlimKeeping It Small with Slim
Keeping It Small with SlimRaven Tools
 

Mais procurados (20)

Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Functionality Focused Code Organization
Functionality Focused Code OrganizationFunctionality Focused Code Organization
Functionality Focused Code Organization
 
Cyclejs introduction
Cyclejs introductionCyclejs introduction
Cyclejs introduction
 
PhoneGap: Local Storage
PhoneGap: Local StoragePhoneGap: Local Storage
PhoneGap: Local Storage
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
 
Sencha Touch - Introduction
Sencha Touch - IntroductionSencha Touch - Introduction
Sencha Touch - Introduction
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End Devs
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patterns
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development Toolkit
 
Backbone js
Backbone jsBackbone js
Backbone js
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
 
Building mobile web apps with Mobello
Building mobile web apps with MobelloBuilding mobile web apps with Mobello
Building mobile web apps with Mobello
 
Keeping It Small with Slim
Keeping It Small with SlimKeeping It Small with Slim
Keeping It Small with Slim
 
Mashing up JavaScript
Mashing up JavaScriptMashing up JavaScript
Mashing up JavaScript
 

Semelhante a Backbone Model and Collection

Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejsNick Lee
 
Heroku pop-behind-the-sense
Heroku pop-behind-the-senseHeroku pop-behind-the-sense
Heroku pop-behind-the-senseBen Lin
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsFrancois Zaninotto
 
前端MVC之BackboneJS
前端MVC之BackboneJS前端MVC之BackboneJS
前端MVC之BackboneJSZhang Xiaoxue
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneRafael Felix da Silva
 
Rapid prototyping and easy testing with ember cli mirage
Rapid prototyping and easy testing with ember cli mirageRapid prototyping and easy testing with ember cli mirage
Rapid prototyping and easy testing with ember cli mirageKrzysztof Bialek
 
Nodejs do teste de unidade ao de integração
Nodejs  do teste de unidade ao de integraçãoNodejs  do teste de unidade ao de integração
Nodejs do teste de unidade ao de integraçãoVinícius Pretto da Silva
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)Igor Bronovskyy
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015Fernando Daciuk
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentNuvole
 
ISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみたISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみたmemememomo
 
Authenticating and Securing Node.js APIs
Authenticating and Securing Node.js APIsAuthenticating and Securing Node.js APIs
Authenticating and Securing Node.js APIsJimmy Guerrero
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 

Semelhante a Backbone Model and Collection (20)

Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
Heroku pop-behind-the-sense
Heroku pop-behind-the-senseHeroku pop-behind-the-sense
Heroku pop-behind-the-sense
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
前端MVC之BackboneJS
前端MVC之BackboneJS前端MVC之BackboneJS
前端MVC之BackboneJS
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com Backbone
 
Backbone js
Backbone jsBackbone js
Backbone js
 
Rapid prototyping and easy testing with ember cli mirage
Rapid prototyping and easy testing with ember cli mirageRapid prototyping and easy testing with ember cli mirage
Rapid prototyping and easy testing with ember cli mirage
 
Nodejs do teste de unidade ao de integração
Nodejs  do teste de unidade ao de integraçãoNodejs  do teste de unidade ao de integração
Nodejs do teste de unidade ao de integração
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Intro to Ember.JS 2016
Intro to Ember.JS 2016Intro to Ember.JS 2016
Intro to Ember.JS 2016
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
 
ISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみたISUCONアプリを Pythonで書いてみた
ISUCONアプリを Pythonで書いてみた
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
Authenticating and Securing Node.js APIs
Authenticating and Securing Node.js APIsAuthenticating and Securing Node.js APIs
Authenticating and Securing Node.js APIs
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 

Último

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 

Último (20)

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 

Backbone Model and Collection

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 31.
  • 32. var Comment = Backbone.Model.extend();
  • 33. var Comment = Backbone.Model.extend(); var comment = new Comment({ id: 83562107 text: " “ ” " created_at: "2011-07-03 09:04:34" user: { uid: "keso" id: "1000185" screen_name: "keso" } });
  • 35. – extend - constructor / initialize – get – set – escape – has – unset – clear – id – cid – attributes – defaults - toJSON
  • 36. comment.get('text'); // “ ” comment.set( {'text':'<script>alert('xss')</script>'}, {silent:true} ); – extend comment.escape('text'); - constructor / initialize // &lt;script&gt;alert(&#x27xss&#x27) – get &lt;&#x2F;script&gt; – set – escape comment.has('city'); // false – has – unset comment.unset('text'); // trigger 'change' event – clear – id – cid – attributes – defaults - toJSON
  • 37. comment.get('text'); // “ ” comment.set( {'text':'<script>alert('xss')</script>'}, {silent:true} ); – extend comment.escape('text'); - constructor / initialize // &lt;script&gt;alert(&#x27xss&#x27) – get &lt;&#x2F;script&gt; – set – escape comment.has('city'); // false – has – unset comment.unset('text'); // trigger 'change' event – clear – id – cid – attributes var Comment = new Backbone.Model.extend({ – defaults // hash or function() - toJSON defaults: { 'source': 'douban.com' }, initialize: function() { ... } }); var comment = new Comment(); comment.get('source'); // 'douban.com'
  • 38. var Comment = new Backbone.Model.extend({ urlRoot: '/comments' initialize: function(attrs) { ... } }); var comment = new Comment({id:123456}); – fetch comment.url(); // '/comments/123456' comment.fetch(); – save – destroy – validate – url – urlRoot var Comment = new Backbone.Model.extend({ – parse initialize: function(attrs) { ... }, – clone validate: function(attrs) { – isNew if ( attrs.text.length < 3 ) { – change return ' 3 ' – hasChanged } – changedAttributes – previous } – previousAttributes }); var comment = new Comment(); comment.set({text:'ok'},{ error: function(model,error) { alert(error); } });
  • 40.
  • 42. var Comments = new Backbone.Collection.extend({ model: Comment, initialize: function(models,options) { } });
  • 43. [ { text: " “ ” " created_at: "2011-07-03 09:04:34" source: "douban.com" user: { city: " " statuses_count: 172 uid: "keso" following_count: 1688 created_at: "2005-04-07 18:01:26" followers_count: 6178 small_avatar: "http://img3.douban.com/icon/u1000185-2.jpg" id: "1000185" screen_name: "keso" ... } id: 83562107 }, {...} {...} ]
  • 44. App.Collections.Comments = Backbone.Collection.extend({ – model – constructor / initialize model: Comment, – models initialize: function(models,options) { – toJSON – Underscore Methods (25) this.url = '/api/statuses/' + options.id + '/comments' – get + (options.count ? '?count=' + options.count : '') – getByCid + (options.page ? '&page=' + options.page : ''); this.page = 1; – at – length }, – comparator comparator: function(model) { – sort return -model.get('id'); – pluck } – url – parse });
  • 49. collection.create(attributes, [options]) var Comments = new Comments([{...}]); Comments.create({text: "It's no big deal!"});
  • 50. collection.create(attributes, [options]) var Comments = new Comments([{...}]); Comments.create({text: "It's no big deal!"});
  • 51. collection.create(attributes, [options]) var Comments = new Comments([{...}]); Comments.create({text: "It's no big deal!"}); var comment = new Comment({ text: "It's no big deal!", }); comment.save(); Comments.add(comment);
  • 52.
  • 53.
  • 55.
  • 56. App.Views.Comment = Backbone.View.extend({ className: 'comment-item', template: $('#comment-item-template').html(), events: { "mouseenter" : "showActions", "mouseleave" : "hideActions" }, initialize: function() { _.bindAll(this, 'render'); this.model.bind('change', this.render); }, render: function() { $(this.el).html(Mustache.to_html(this.template, this.model.toJSON())); $(this.el).attr({ 'data-item-id': this.model.id, 'data-comment-id': this.model.id }); return this; }, showActions: function(e) { this.$('.icon-delete').show(); }, hideActions: function(e) { this.$('.icon-delete').hide(); } });
  • 57. App.Views.Comment = Backbone.View.extend({ className: 'comment-item', template: $('#comment-item-template').html(), events: { "mouseenter" : "showActions", "mouseleave" : "hideActions" }, initialize: function() { _.bindAll(this, 'render'); this.model.bind('change', this.render); }, render: function() { $(this.el).html(Mustache.to_html(this.template, this.model.toJSON())); $(this.el).attr({ 'data-item-id': this.model.id, 'data-comment-id': this.model.id }); return this; }, showActions: function(e) { this.$('.icon-delete').show(); }, var view = new App.Views.Comment({ hideActions: function(e) { model: model this.$('.icon-delete').hide(); }); } }); $('body').append(view.render().el);
  • 58.
  • 59. App.Router.Shuo = Backbone.Router.extend({ routes: { "" : "home", ":uid" : "profile", ":uid/following" : "following", ":uid/status/:id" : "permalink", "search/:query" : "search" }, initialize: function() { Backbone.history.start({pushState: true, root:'/'}); }, home: function() { App.Pages.Home = new App.Views.Home(); oBody.append(App.Pages.Home.render().el); this.navigate(''); }, profile: function(uid) { App.Pages.Profile[uid] = new App.Views.Profile({uid: uid}); oBody.append(App.Pages.Profile[uid].render().el); this.navigate(uid,true); }, following: function(uid) { ... permalink: function(uid,id) { ... search: function(query) { ... });
  • 60. router.route(route, name, callback) initialize: function(options) { // Matches #page/10, passing "10" this.route("page/:number", "page", function(number){ ... }); // Matches /117-a/b/c/open, passing "117-a/b/c" this.route(/^(.*?)/open$/, "open", function(id){ ... }); }
  • 62. Backbone.history.start([options]) App.Router.Shuo = Backbone.Router.extend({ routes: { "" : "home", ":uid" : "profile", ":uid/following" : "following", ":uid/status/:id" : "permalink", "search/:query" : "search" }, initialize: function() { Backbone.history.start({pushState: true, root:'/'}); }, ...
  • 63. Backbone.Events ◦ "add" (model, collection) — when a model is added to a collection. ◦ "remove" (model, collection) — when a model is removed from a collection. ◦ "reset" (collection) — when the collection's entire contents have been replaced. ◦ "change" (model, collection) — when a model's attributes have changed. ◦ "change:[attribute]" (model, collection) — when a specific attribute has been updated. ◦ "destroy" (model, collection) — when a model is destroyed. ◦ "error" (model, collection) — when a model's validation fails, or a save call fails on the server. ◦ "route:[name]" (router) — when one of a router's routes has matched. ◦ "all" — this special event fires for any triggered event, passing the event name as the first argument.
  • 64. object.bind(event, callback) App.Views.Comment = Backbone.View.extend({ className: 'comment-item', template: $('#comment-item-template').html(), initialize: function() { _.bindAll(this, 'render'); this.model.bind('change', this.render); }, render: function() { $(this.el).html(Mustache.to_html(this.template, this.model.toJSON())); $(this.el).attr({ 'data-item-id': this.model.id, 'data-comment-id': this.model.id }); return this; } });
  • 65. Backbone.sync is the function that Backbone calls every time it attempts to read or save a model to the server. By default, it uses (jQuery/Zepto).ajax to make a RESTful JSON request. You can override it in order to use a different persistence strategy, such as WebSockets, XML transport, or Local Storage.
  • 66.
  • 68. Models Collections Interactive Data Domain- Ordered Sets of Models specific methods
  • 69. Models Collections Interactive Data Domain- Ordered Sets of Models specific methods Views Render HTML/CSS With Javascript templating
  • 70. Models Collections Interactive Data Domain- Ordered Sets of Models specific methods Views Router Render HTML/CSS With Methods For Routing URL Javascript templating Fragments
  • 71. Models Collections Interactive Data Domain- Ordered Sets of Models specific methods Views Router Render HTML/CSS With Methods For Routing URL Javascript templating Fragments
  • 72. Models Collections Interactive Data Domain- Ordered Sets of Models specific methods Views Router Render HTML/CSS With Methods For Routing URL Javascript templating Fragments
  • 75. public/js -- /libs/ |- jquery.js |- backbone.js |- underscore.js |- json2.js |- mustache.js |- cacheprovider.js -- /applications.js -- /models/ -- /collections/ -- /views/ -- /controllers/
  • 77. var App = { Views: {}, Router: {}, Collections: {}, Cache: new CacheProvider(), initialize: function(){ new App.Router.Shuo(); Backbone.history.start({pushState: true}); } }; public/js/application.js
  • 78. App.Routers.Shuo = Backbone.Router.extend({ routes: { "" : "home", "comments" : "comments", "mentions" : "mentions", ":uid" : "profile", ":uid/following" : "following", ":uid/followers" : "followers", ":uid/status/:id" : "permalink", "search/users/:query" : "user_search", "search/:query" : "search" }, initialize: function() { ... }, home: function() { ... }, comments: function() { ... }, mentions: function() { ... }, profile: function(uid) { ... }, following: function(uid) { ... }, followers: function(uid) { ... }, permalink: function(uid,id) { ... }, user_search: function(query) { ... }, search: function(query) { ... } }); public/js/controllers/shuo.js
  • 81. public/js/models |- comment.js |- comment_notification.js |- mention.js |- stat.js |- status.js |- user.js
  • 84. public/js/collections |- comments.js |- follow_in_common.js |- followers.js |- home_timeline.js |- likers.js |- mentions.js |- resharers.js |- results.js |- suggestions.js |- user_recommendations.js |- user_results.js |- user_timeline.js |- users.js
  • 86.
  • 87. Home
  • 88.
  • 89. Main
  • 90. Main Dashboard
  • 91.
  • 93. HomeHeader Navigation Following Followers Suggestion Stream ADs Footer
  • 94.
  • 97. new App.Views.StreamItem(); model: Status Status model.fetch() this.render() Resharers Comments
  • 98. new App.Views.StreamItem(); model: Status Status model.fetch() this.render() Resharers new App.Views.Resharers()... Comments
  • 99. new App.Views.StreamItem(); model: Status Status model.fetch() this.render() Resharers new App.Views.Resharers()... new App.Views.Comments() this.collection = new Comments([],{ id: status.id Comments }); this.collection.fetch() this.collection.create() this.collection.remove()
  • 100. ... <div id="page-outer"> </div> ... <script id="status-item-template" type="text/template">...</script> <script id="comment-item-template" type="text/template">...</script> ... template/app.html
  • 101. App.Views.Permalink = Backbone.View.extend({ el: oDoc, initialize: function(options) { _.bindAll(this, 'render', 'loadStatus', 'loadResharers', 'loadLikers', 'loadComments'); var self = this; $.ajax('/api/statuses/' + options.id + '?pack=1&comment_count=50&reshare_count=14&like_count=14') .success(function(resp) { self.status = new Status(resp.status, {id: options.id}); self.comments = new App.Collections.Comments(resp.comments, {id: options.id}); self.resharers = new App.Collections.Resharers(resp.reshare_users, {id: options.id}); self.loadStatus(); }) .error(function(resp){ // 404 } }); }, render: function() { return this; }, loadStatus: function() { var view = new App.Views.StreamItem({ model: this.status }); this.loadComments(); this.loadResharers(); oPageContainer.prepend(view.render().el); }, loadResharers: function() { ... }, loadComments: function() { ... } }); public/js/views/permalink.js
  • 102. App.Views.Permalink = Backbone.View.extend({ ... loadComments: function() { var view = new App.Views.Comments({ model: this.status, collection: this.comments }); oPageContainer.prepend(view.render().el); } }); public/js/views/permalink.js
  • 103. App.Views.Comments = Backbone.View.extend({ className: 'comments-manager', template: $('#comments-components-template').html(), title_template: '{{#comments_count}}<h3>{{comments_count}} </h3>{{/comments_count}}', events: { "click .submit" : "submitComment", }, initialize: function(options) { _.bindAll(this,'render', 'loadTitle', 'loadOne', 'loadAll'); this.status = options.status; this.collection.bind('add', this.loadOne); this.collection.bind('remove', this.loadAll); this.collection.bind('reset', this.loadAll); }, render: function() { $(this.el).html(Mustache.to_html(this.template,{ logged_out: !shuo.loggedIn })); this.title = this.$('.comments-title'); this.oBnSubmit = this.$('.submit-area input'); this.comments = this.$('.comments-items'); this.loadTitle(this.status.toJSON()); this.loadAll(); return this; }, loadOne: function(model) { if ( model.isNew() ) { var view = new App.Views.Comment({ model: model }); this.comments.append(view.render().el); } }, loadTitle: function(data) { this.title.html(Mustache.to_html(this.title_template,data)); }, loadAll: function() { public/js/views/comments.js }, this.collection.each(this.loadOne); create: function(e) {
  • 108. { entities: { user_mentions: [], urls: [] } text: " “ ” " created_at: "2011-07-03 09:04:34" source: "douban.com" user: { city: " " icon_avatar: "http://img3.douban.com/icon/ui1000185-2.jpg" statuses_count: 172 uid: "keso" following_count: 1688 url: "" created_at: "2005-04-07 18:01:26" description: "keso http:// blog.donews.com/keso" followers_count: 6178 location: " " small_avatar: "http://img3.douban.com/icon/u1000185-2.jpg" following: false verified: false large_avatar: "http://img3.douban.com/icon/ul1000185-2.jpg" id: "1000185" screen_name: "keso" } id: 83562107 }
  • 109. <script id="comment-item-template" type="text/template"> <div class="comment-item-content" data-user-id="{{#user}}{{uid}}{{/user}}" data-item-id="{{id}}" data- comment-id="{{id}}"> {{#user}} <div class="icon"> <a href="/#{{uid}}"><img src="{{small_avatar}}" alt="{{screen_name}}"/></a> </div> {{/user}} <div class="content"> <p> {{#user}} <a href="/#!/{{uid}}" class="to" title="{{uid}}">{{screen_name}}</a> {{/user}} <span class="comment-time">{{timestamp}}</span> </p> <p> <span class="comment-text">{{{text}}}</span> <a href="" class="icon-comment" title=" "><img src="http://img3.douban.com/anduin/pics/ blank.gif"/></a> </p> </div> </div> </script>
  • 112.
  • 115.