【前端Mvc】之豆瓣说实践

14,552 views
14,454 views

Published on

Published in: Technology
0 Comments
33 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
14,552
On SlideShare
0
From Embeds
0
Number of Embeds
4,294
Actions
Shares
0
Downloads
387
Comments
0
Likes
33
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • 豆瓣说首页截图 点击截图 连接线上真实环境 演示以下几个特征\n1.Single Page App 页面跳转无刷新\n2.History 管理(url特点)\n3.基于API开发\n有要动画\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • 上截图 单条页面 即可 \n因为包含了model 及collection的实例\n依照截图 分析出页面中的model及collection\n
  • 上截图 单条页面 即可 \n因为包含了model 及collection的实例\n依照截图 分析出页面中的model及collection\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • 可列举comments 或者在status基础上列举hometimeline来说明collection的定义\n
  • \n
  • \n
  • 可列举comments 或者在status基础上列举hometimeline来说明collection的定义\n
  • \n
  • 可列举comments 或者在status基础上列举hometimeline来说明collection的定义\n
  • \n
  • \n
  • 上图 展示以上这部分代码相应的view\n
  • 可列举comments 或者在status基础上列举hometimeline来说明collection的定义\n
  • 上截图 单条页面 即可 \n因为包含了model 及collection的实例\n依照截图 分析出页面中的model及collection\n
  • 上截图 单条页面 即可 \n因为包含了model 及collection的实例\n依照截图 分析出页面中的model及collection\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • 【前端Mvc】之豆瓣说实践

    1. 1. MVC[ ]
    2. 2. ,“ ”
    3. 3. BackboneJS
    4. 4. UnderscoreJSMustacheJS json2 BackboneJS jQuery CacheProviderJS
    5. 5. UnderscoreJSMustacheJS BackboneJS
    6. 6. BackboneJSMustacheJSUnderscoreJS
    7. 7. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

    8. 8. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

    9. 9. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

    10. 10. It’s a Javascript library for writing applications like....
    11. 11. It’s a Javascript library for writing applications like....
    12. 12. It’s a Javascript library for writing applications like....
    13. 13. It’s a Javascript library for writing applications like....
    14. 14. Javascript Web Application
    15. 15. Downloads & DependenciesDevelopment Version (0.5.1) 41kb, Full Source with CommentsProduction Version (0.5.1) 4.6kb, Packed and GzippedBackbones only hard dependency is Underscore.js.For RESTful persistence, history support via Backbone.ControllerRouter andDOM manipulation with Backbone.View, include json2.js, and either jQuery( > 1.4.2) or Zepto.
    16. 16. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

    17. 17. Backbone.Model• Models contain the data• Validations,properties and permissions• Manage changes to the above
    18. 18. var Comment = Backbone.Model.extend();
    19. 19. 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" }});
    20. 20. Backbone.Model• Models contain the data• Validations,properties and permissions• Manage changes to the above
    21. 21. comment.get(text); // “ ” comment.set( {text:<script>alert(xss)</script>}, {silent:true} ); comment.escape(text);– extend //- constructor / initialize &lt;script&gt;alert(&#x27xss&#x27)&lt;/script&gt– get ;– set– escape comment.has(city); // false– has– unset– clear comment.unset(text); // trigger change event– 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
    22. 22. var Comment = new Backbone.Model.extend({ urlRoot: /comment initialize: function(attrs) { ... } }); var comment = new Comment({id:123456});– fetch comment.url(); // /comment/123456– save– destroy– validate– url– urlRoot var Comment = new Backbone.Model.extend({– parse urlRoot: /comment– clone initialize: function(attrs) { ... },– isNew validate: function(attrs) {– change if ( attrs.text.length < 3 ) {– hasChanged return 3 – changedAttributes }– previous }– previousAttributes }); var comment = new Comment(); comment.set({text:ok},{ error: function(model,error) { alert(error); } });
    23. 23. Backbone.Model• Models contain the data• Validations,properties and permissions• Manage changes to the above
    24. 24. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

    25. 25. Backbone.Collection• Collections are ordered sets of models• Act on events within models• Add, Remove, Fetch, Refresh, Create, Sort
    26. 26. var Comments = new Backbone.Collection.extend({ model: Comment, initialize: function(models,options) { }});
    27. 27. [ { 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 }, {...} {...}]
    28. 28. Backbone.Collection• Collections are ordered sets of models• Act on events within models• Add, Remove, Fetch, Refresh, Create, Sort
    29. 29. 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 });
    30. 30. Backbone.Collection• Collections are ordered sets of models• Act on events within models• Add, Remove, Fetch, Refresh, Create, Sort
    31. 31. User = new Backbone.Model.extend({ initialize: function(attrs) { this.url = /users/ + attrs.id; } }); var user = new User({id: 2770683});– add user.fetch({– remove success:function(model,resp) {– fetch document.title = model.get(screen_name) + / ;– reset App.Pages.Profile = new App.Views.Profile({ model: model– create }); oBody.append(App.Pages.Profile.render().el); }, error: function(model,resp) { switch (resp.status) { case 404: App.Pages.Error = new App.Views.Error({ msg: }); oBody.append(App.Pages.Error.render().el); break; } } });
    32. 32. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

    33. 33. Backbone.View
    34. 34. Backbone.View• A logical UI component, not just the template• They are more like Rail’s Controller• Responsible for instantiating Collections and binding events that update the UI
    35. 35. App.Views.Comment = Backbone.View.extend({ className: comment-item, template: $(#comment-item-template).html(), events: { "mouseover" : "showActions", "mouseout" : "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);
    36. 36. Router Backbone.ControllerProvides methods for routing client-side URLfragments, and connecting them to actionsand events.
    37. 37. 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) { ...});
    38. 38. 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){ ... }); }
    39. 39. Backbone.History• A global router (per frame) to handle hashchange events or pushState• Match the appropriate route, and trigger callbacks
    40. 40. 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:/}); }, ...
    41. 41. 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 collections entire contents have been replaced.◦ "change" (model, collection) — when a models 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 models validation fails, or a save call fails on the server.◦ "route:[name]" (router) — when one of a routers routes has matched.◦ "all" — this special event fires for any triggered event, passing the event name as the first argument.
    42. 42. 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; } });
    43. 43. Backbone.SyncBackbone.sync is the function that Backbone calls every time itattempts to read or save a model to the server. By default, it uses(jQuery/Zepto).ajax to make a RESTful JSON request. You canoverride it in order to use a different persistence strategy, such asWebSockets, XML transport, or Local Storage.
    44. 44. ModelsInteractive Data Domain- specific methods
    45. 45. Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods
    46. 46. Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods Views Render HTML/CSS With Javascript templating
    47. 47. Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods Views Router Render HTML/CSS With Methods For Routing URL Javascript templating Fragments
    48. 48. Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods Views Router Render HTML/CSS With Methods For Routing URL Javascript templating Fragments
    49. 49. Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods Views Router Render HTML/CSS With Methods For Routing URL Javascript templating Fragments
    50. 50. public/js
    51. 51. ../libs/ jquery.js backbone.js underscore.js json2.js mustache.js cacheprovider.js../applications.js../models/../collections/../views/../controllers/
    52. 52. ../application.js
    53. 53. var App = { Views: {}, Router: {}, Collections: {}, Cache: new CacheProvider(), initialize: function(){ new App.Controllers.Shuo(); Backbone.history.start({pushState: true}); } };public/js/application.js
    54. 54. 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
    55. 55. public/js/models
    56. 56. public/js/models
    57. 57. public/js/modelscomment.jscomment_notification.jsmention.jsrecommend.jsstat.jsstatus.jsuser.js
    58. 58. public/js/collections
    59. 59. public/js/collections
    60. 60. public/js/collectionscomment_notifications.jscomments.jsfollow_in_common.jsfollowers.jsfollowing.jsfollowing_followers_of.jshome_timeline.jslikers.jsmentions.jsrecommend_list.jsresharers.jsresults.jssuggestions.jsuser_recommendations.jsuser_results.jsuser_timeline.jsusers.js
    61. 61. public/js/views
    62. 62. Home
    63. 63. Main
    64. 64. Main Dashboard
    65. 65. HomeHeader Stream
    66. 66. HomeHeader Navigation Following Followers Suggestion Stream ADs Footer
    67. 67. StatusResharersComments
    68. 68. StatusResharersComments
    69. 69. new App.Views.StreamItem(); model: Status Status model.fetch() this.render()ResharersComments
    70. 70. new App.Views.StreamItem(); model: Status Status model.fetch() this.render()Resharers new App.Views.Resharers()...Comments
    71. 71. 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.idComments }); this.collection.fetch() this.collection.add() this.collection.remove()
    72. 72. ... <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
    73. 73. App.Views.Permalink = Backbone.View.extend({ el: oDoc, item_template: $(#permalink-item-template).html(), 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
    74. 74. App.initialize();
    75. 75. BackboneJSMustacheJSUnderscoreJS
    76. 76. BackboneJSMustacheJSUnderscoreJS
    77. 77. MustacheJS
    78. 78. { 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}
    79. 79. <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>
    80. 80. Mustache.to_html(template,data);
    81. 81. MustacheJS 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

    82. 82. Mustache 2.0 Feature Requests
    83. 83. BackboneJSMustacheJSUnderscoreJS
    84. 84. About Me
    85. 85. : It’s no big deal!
    86. 86. EndThanks!

    ×