Your SlideShare is downloading. ×
0
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
前端MVC 豆瓣说
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

前端MVC 豆瓣说

11,924

Published on

Published in: Technology
4 Comments
47 Likes
Statistics
Notes
No Downloads
Views
Total Views
11,924
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
361
Comments
4
Likes
47
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. •••
  • 2. var Comment = Backbone.Model.extend();
  • 3. 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" }});
  • 4. •••
  • 5. – extend- constructor / initialize– get– set– escape– has– unset– clear– id– cid– attributes– defaults- toJSON
  • 6. comment.get(text); // “ ” comment.set( {text:<script>alert(xss)</script>}, {silent:true} );– extend comment.escape(text);- constructor / initialize // <script>alert(&#x27xss&#x27)– get </script>– set– escape comment.has(city); // false– has– unset comment.unset(text); // trigger change event– clear– id– cid– attributes– defaults- toJSON
  • 7. comment.get(text); // “ ” comment.set( {text:<script>alert(xss)</script>}, {silent:true} );– extend comment.escape(text);- constructor / initialize // <script>alert(&#x27xss&#x27)– get </script>– 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
  • 8. 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); } });
  • 9. •••
  • 10. •••
  • 11. var Comments = new Backbone.Collection.extend({ model: Comment, initialize: function(models,options) { }});
  • 12. [ { 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 }, {...} {...}]
  • 13. 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 });
  • 14. •••
  • 15. •••
  • 16. collection.create(attributes, [options])
  • 17. collection.create(attributes, [options])var Comments = new Comments([{...}]);
  • 18. collection.create(attributes, [options])var Comments = new Comments([{...}]);Comments.create({text: "Its no big deal!"});
  • 19. collection.create(attributes, [options])var Comments = new Comments([{...}]);Comments.create({text: "Its no big deal!"});
  • 20. collection.create(attributes, [options])var Comments = new Comments([{...}]);Comments.create({text: "Its no big deal!"});var comment = new Comment({ text: "Its no big deal!",});comment.save();Comments.add(comment);
  • 21. •••
  • 22. 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(); }});
  • 23. 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);
  • 24. 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) { ...});
  • 25. 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){ ... }); }
  • 26. ••
  • 27. 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:/}); }, ...
  • 28. 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.
  • 29. 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; } });
  • 30. Backbone.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.
  • 31. ModelsInteractive Data Domain- specific methods
  • 32. Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods
  • 33. Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods Views Render HTML/CSS With Javascript templating
  • 34. Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods Views Router Render HTML/CSS With Methods For Routing URL Javascript templating Fragments
  • 35. Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods Views Router Render HTML/CSS With Methods For Routing URL Javascript templating Fragments
  • 36. Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods Views Router Render HTML/CSS With Methods For Routing URL Javascript templating Fragments
  • 37. public/js
  • 38. public/js
  • 39. public/js-- /libs/ |- jquery.js |- backbone.js |- underscore.js |- json2.js |- mustache.js |- cacheprovider.js-- /applications.js-- /models/-- /collections/-- /views/-- /controllers/
  • 40. ../application.js
  • 41. var App = { Views: {}, Router: {}, Collections: {}, Cache: new CacheProvider(), initialize: function(){ new App.Router.Shuo(); Backbone.history.start({pushState: true}); } };public/js/application.js
  • 42. 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
  • 43. public/js/models
  • 44. public/js/models
  • 45. public/js/models|- comment.js|- comment_notification.js|- mention.js|- stat.js|- status.js|- user.js
  • 46. public/js/collections
  • 47. public/js/collections
  • 48. 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
  • 49. public/js/views
  • 50. Home
  • 51. Main
  • 52. Main Dashboard
  • 53. HomeHeader Stream
  • 54. HomeHeader Navigation Following Followers Suggestion Stream ADs Footer
  • 55. StatusResharersComments
  • 56. StatusResharersComments
  • 57. new App.Views.StreamItem(); model: Status Status model.fetch() this.render()ResharersComments
  • 58. new App.Views.StreamItem(); model: Status Status model.fetch() this.render()Resharers new App.Views.Resharers()...Comments
  • 59. 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.create() this.collection.remove()
  • 60. ... <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
  • 61. 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
  • 62. 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
  • 63. 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) {
  • 64. App.initialize();
  • 65. BackboneJSMustacheJSUnderscoreJS
  • 66. BackboneJSMustacheJSUnderscoreJS
  • 67. MustacheJS
  • 68. { 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}
  • 69. <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>
  • 70. Mustache.to_html(template,data);
  • 71. MustacheJS
  • 72. BackboneJSMustacheJSUnderscoreJS
  • 73. UnderscoreJS
  • 74. http://shuo.douban.com/imdonkey

×