• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
前端MVC 豆瓣说
 

前端MVC 豆瓣说

on

  • 11,831 views

 

Statistics

Views

Total Views
11,831
Views on SlideShare
9,028
Embed Views
2,803

Actions

Likes
46
Downloads
350
Comments
4

12 Embeds 2,803

http://imdonkey.com 1501
http://www.niutian365.com 1129
url_unknown 57
http://fe.com 43
http://web.vabx.com 34
http://www.zhuaxia.com 15
http://cache.baidu.com 15
http://www.techgig.com 4
http://search.panguso.com 2
http://192.168.0.138 1
http://imdonkey.com} {975597377|||pingback 1
http://zhuaxia.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

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

14 of 4 previous next Post a comment

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    前端MVC 豆瓣说 前端MVC 豆瓣说 Presentation Transcript

    • •••
    • 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: "Its no big deal!"});
    • collection.create(attributes, [options])var Comments = new Comments([{...}]);Comments.create({text: "Its no big deal!"});
    • 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);
    • •••
    • 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 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.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
    • 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
    • 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.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();
    • 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
    • BackboneJSMustacheJSUnderscoreJS
    • UnderscoreJS
    • http://shuo.douban.com/imdonkey