• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
【前端Mvc】之豆瓣说实践
 

【前端Mvc】之豆瓣说实践

on

  • 14,298 views

 

Statistics

Views

Total Views
14,298
Views on SlideShare
10,009
Embed Views
4,289

Actions

Likes
31
Downloads
371
Comments
0

16 Embeds 4,289

http://www.d2forum.org 4220
http://qianduan.me 29
http://www.itfeed.cn 12
http://cache.baidu.com 9
http://www.icode.cc 5
http://localhost 2
http://getpocket.com 2
http://reader.youdao.com 2
http://www.d2forum.org} {218108811|||pingback 1
http://www.d2forum.org} {1245521219|||pingback 1
http://www.d2forum.org} {1194494595|||pingback 1
http://www.d2forum.org} {405771438|||pingback 1
http://www.d2forum.org} {165085881||||} "GET 1
http://www.d2forum.org} {213252766|||pingback 1
http://www.d2forum.org} {713730707|||pingback 1
http://www.d2forum.org} {875854193|||pingback 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \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】之豆瓣说实践 【前端Mvc】之豆瓣说实践 Presentation Transcript

  • MVC[ ]
  • ,“ ”
  • BackboneJS
  • UnderscoreJSMustacheJS json2 BackboneJS jQuery CacheProviderJS
  • UnderscoreJSMustacheJS BackboneJS
  • BackboneJSMustacheJSUnderscoreJS
  • 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

  • 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

  • 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

  • It’s a Javascript library for writing applications like....
  • It’s a Javascript library for writing applications like....
  • It’s a Javascript library for writing applications like....
  • It’s a Javascript library for writing applications like....
  • Javascript Web Application
  • 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.
  • 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

  • Backbone.Model• Models contain the data• Validations,properties and permissions• Manage changes to the above
  • 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" }});
  • Backbone.Model• Models contain the data• Validations,properties and permissions• Manage changes to the above
  • 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;&#x2F;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
  • 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); } });
  • Backbone.Model• Models contain the data• Validations,properties and permissions• Manage changes to the above
  • 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

  • Backbone.Collection• Collections are ordered sets of models• Act on events within models• Add, Remove, Fetch, Refresh, Create, Sort
  • 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 }, {...} {...}]
  • Backbone.Collection• Collections are ordered sets of models• Act on events within models• Add, Remove, Fetch, Refresh, Create, Sort
  • 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 });
  • Backbone.Collection• Collections are ordered sets of models• Act on events within models• Add, Remove, Fetch, Refresh, Create, Sort
  • 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; } } });
  • 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

  • Backbone.View
  • 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
  • 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);
  • Router Backbone.ControllerProvides methods for routing client-side URLfragments, and connecting them to actionsand events.
  • 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• A global router (per frame) to handle hashchange events or pushState• Match the appropriate route, and trigger callbacks
  • 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 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.
  • 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.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.
  • ModelsInteractive Data Domain- specific methods
  • Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods
  • Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods Views Render HTML/CSS With Javascript templating
  • Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods Views Router Render HTML/CSS With Methods For Routing URL Javascript templating Fragments
  • Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods Views Router Render HTML/CSS With Methods For Routing URL Javascript templating Fragments
  • Models CollectionsInteractive Data Domain- Ordered Sets of Models specific methods Views Router Render HTML/CSS With Methods For Routing URL Javascript templating Fragments
  • 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.Controllers.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/modelscomment.jscomment_notification.jsmention.jsrecommend.jsstat.jsstatus.jsuser.js
  • public/js/collections
  • public/js/collections
  • 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
  • public/js/views
  • Home
  • Main
  • Main Dashboard
  • HomeHeader Stream
  • HomeHeader Navigation Following Followers Suggestion Stream ADs Footer
  • StatusResharersComments
  • StatusResharersComments
  • new App.Views.StreamItem(); model: Status Status model.fetch() this.render()ResharersComments
  • 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.idComments }); this.collection.fetch() this.collection.add() 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, 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
  • App.initialize();
  • BackboneJSMustacheJSUnderscoreJS
  • BackboneJSMustacheJSUnderscoreJS
  • 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 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

  • Mustache 2.0 Feature Requests
  • BackboneJSMustacheJSUnderscoreJS
  • About Me
  • : It’s no big deal!
  • EndThanks!