<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] ## MVC框架 隨著JavaScript程序變得越來越復雜,往往需要一個團隊協作開發,這時代碼的模塊化和組織規范就變得異常重要了。MVC模式就是代碼組織的經典模式。 > (……MVC介紹。) > (1)Model > Model表示數據層,也就是程序需要的數據源,通常使用JSON格式表示。 > (2)View > View表示表現層,也就是用戶界面,對于網頁來說,就是用戶看到的網頁HTML代碼。 > (3)Controller > Controller表示控制層,用來對原始數據(Model)進行加工,傳送到View。 由于網頁編程不同于客戶端編程,在MVC的基礎上,JavaScript社區產生了各種變體框架MVP(Model-View-Presenter)、MVVM(Model-View-ViewModel)等等,有人就把所有這一類框架的各種模式統稱為MV*。 框架的優點在于合理組織代碼、便于團隊合作和未來的維護,缺點在于有一定的學習成本,且限制你只能采取它的寫法。 ## 零框架解決方案 MVC框架(尤其是大型框架)有一個嚴重的缺點,就是會產生用戶的重度依賴。一旦框架本身出現問題或者停止更新,用戶的處境就會很困難,維護和更新成本極高。 ES6的到來,使得JavaScript語言有了原生的模塊解決方案。于是,開發者有了另一種選擇,就是不使用MVC框架,只使用各種單一用途的模塊庫,組合完成一個項目。下面是可供選擇的各種用途的模塊列表。 輔助功能庫(Helper Libraries) * [moment.js](http://momentjs.com/):日期和時間的標準化 * [underscore.js](http://underscorejs.org/)?/?[Lo-Dash](https://lodash.com/):一系列函數式編程的功能函數 路由庫(Routing) * [router.js](https://github.com/tildeio/router.js/):Ember.js使用的路由庫 * [route-recognizer](https://github.com/tildeio/route-recognizer):功能全面的路由庫 * [page.js](https://github.com/visionmedia/page.js):類似Express路由的庫 * [director](https://github.com/flatiron/director):同時支持服務器和瀏覽器的路由庫 Promise庫 * [RSVP.js](https://github.com/tildeio/rsvp.js):ES6兼容的Promise庫 * [ES6-Promise](https://github.com/jakearchibald/es6-promise):RSVP.js的子集,但是全面兼容ES6 * [q](https://github.com/kriskowal/q):最常用的Promise庫之一,AngularJS用了它的精簡版 * [native-promise-only](https://github.com/getify/native-promise-only):嚴格符合ES6的Promise標準,同時兼容老式瀏覽器 客戶端與服務器的通信庫 * [fetch](https://github.com/github/fetch):實現window.fetch功能 * [qwest](https://github.com/pyrsmk/qwest):支持XHR2和Promise的Ajax庫 * [jQuery](https://github.com/jquery/jquery):jQuery 2.0支持按模塊打包,因此可以創建一個純Ajax功能庫 動畫庫(Animation) * [cssanimevent](https://github.com/magnetikonline/cssanimevent):兼容老式瀏覽器的CSS3動畫庫 * [Velocity.js](http://julian.com/research/velocity/):性能優秀的動畫庫 輔助開發庫(Development Assistance) * [LogJS](https://github.com/bfattori/LogJS):輕量級的logging功能庫 * [UserTiming.js](https://github.com/nicjansma/usertiming.js):支持老式瀏覽器的高精度時間戳庫 流程控制和架構(Flow Control/Architecture) * [ondomready](https://github.com/tubalmartin/ondomready):類似jQuery的ready()方法,符合AMD規范 * [script.js](https://github.com/ded/script.js%5D):異步的腳本加載和依賴關系管理庫 * [async](https://github.com/caolan/async):瀏覽器和node.js的異步管理工具庫 * [Virtual DOM](https://github.com/Matt-Esch/virtual-dom):react.js的一個替代方案,參見[Virtual DOM and diffing algorithm](https://gist.github.com/Raynos/8414846) 數據綁定(Data-binding) * Object.observe():Chrome已經支持該方法,可以輕易實現雙向數據綁定 模板庫(Templating) * [Mustache](http://mustache.github.io/):大概是目前使用最廣的不含邏輯的模板系統 微框架(Micro-Framework) 某些情況下,可以使用微型框架,作為項目開發的起點。 * [bottlejs](https://github.com/young-steveo/bottlejs):提供惰性加載、中間件鉤子、裝飾器等功能 * [Stapes.js](http://hay.github.io/stapes/#top):微型MVC框架 * [soma.js](http://somajs.github.io/somajs/site/):提供一個松耦合、易測試的架構 * [knockout](http://knockoutjs.com/):最流行的微框架之一,主要關注UI ## Backbone的加載 ~~~ <script src="/javascripts/lib/jquery.js"></script> <script src="/javascripts/lib/underscore.js"></script> <script src="/javascripts/lib/backbone.js"></script> <script src="/javascripts/jst.js"></script> <script src="/javascripts/router.js"></script> <script src="/javascripts/init.js"></script> ~~~ ## Backbone的用法 Backbone是最早的JavaScript MVC框架,也是最簡化的一個框架。它的設計思想是,只提供最基本的功能,給用戶提供最大的自由。這意味著,好的一面是它沒有一整套規則,強制你接受,壞的一面是很多功能你必須自己實現。Backbone的體積相當小,最小化后只有30多KB。 定義一個對象,表示Web應用。 ~~~ var AppName = { Models :{}, Views :{}, Collections :{}, Controllers :{} }; ~~~ 上面代碼表示,應用由四部分組成:Model、Collection、Controller和View。 定義Model,表示數據的一個基本單位。 ~~~ AppName.Models.Person = Backbone.Model.extend({ urlRoot: "/persons" }); ~~~ 定義Collection,表示Model的集合。 ~~~ AppName.Collections.Library = Backbone.Collection.extend({ model: AppName.Models.Book }); ~~~ 上面代碼表示,Collection對象必須有model屬性,指明由哪一個model構成。 定義一個View。 ~~~ AppName.Views.Modals.AcceptDecline = Backbone.View.Extend({ el: ".modal-accept", events: { "ajax:success .link-accept" :"acceptSuccess", "ajax:error .link-accept" :"acceptError" }, acceptSuccess :function(evt, response) { this.$el.modal("hide"); alert('Cool! Thanks'); }, acceptError :function(evt, response) { var $modalContent = this.$el.find('.panel-modal'); $modalContent.append("Something was wrong!"); } }); ~~~ View對象必須有el屬性,指明當前View綁定的DOM節點,events屬性指明事件和對應的方法。 定義一個Controller。 ~~~ AppName.Controllers.Person = {}; AppName.Controllers.Person.show = function(id) { var aMa = new AppName.Models.Person({id: id}); aMa.updateAge(25); aMa.fetch().done(function(){ var view = new AppName.Views.Show({model: aMa}); }); }; ~~~ 最后,定義路由,啟動應用程序。 ~~~ var Workspace = Backbone.Router.extend({ routes: { "*" :"wholeApp", "users/:id" :"usersShow", "users/:id/orders/" :"ordersIndex" }, wholeApp :AppName.Controller.Application.default, usersShow :AppName.Controller.Users.show, ordersIndex :AppName.Controller.Orders.index }); new Workspace(); Backbone.history.start({pushState: true}); ~~~ ## Backbone.View ### 基本用法 Backbone.View方法用于定義視圖類。 ~~~ var AppView = Backbone.View.extend({ render: function(){ $('main').append('<h1>一級標題</h1>'); } }); ~~~ 上面代碼通過Backbone.View的extend方法,定義了一個視圖類AppView。該類內部有一個render方法,用于將視圖放置在網頁上。 使用的時候,需要先新建視圖類的實例,然后通過實例,調用render方法,從而讓視圖在網頁上顯示。 ~~~ var appView = new AppView(); appView.render(); ~~~ 上面代碼新建視圖類AppView的實例appView,然后調用appView.render,網頁上就會顯示指定的內容。 新建視圖實例時,通常需要指定Model。 ~~~ var document = new Document({ model: doc }); ~~~ ### initialize方法 視圖還可以定義initialize方法,生成實例的時候,會自動調用該方法對實例初始化。 ~~~ var AppView = Backbone.View.extend({ initialize: function(){ this.render(); }, render: function(){ $('main').append('<h1>一級標題</h1>'); } }); var appView = new AppView(); ~~~ 上面代碼定義了initialize方法之后,就省去了生成實例后,手動調用appView.render()的步驟。 ### el屬性,$el屬性 除了直接在render方法中,指定“視圖”所綁定的網頁元素,還可以用視圖的el屬性指定網頁元素。 ~~~ var AppView = Backbone.View.extend({ el: $('main'), render: function(){ this.$el.append('<h1>一級標題</h1>'); } }); ~~~ 上面的代碼與render方法直接綁定網頁元素,效果完全一樣。上面代碼中,除了el屬性,還是$el屬性,前者代表指定的DOM元素,后者則表示該DOM元素對應的jQuery對象。 ### tagName屬性,className屬性 如果不指定el屬性,也可以通過tagName屬性和className屬性指定。 ~~~ var Document = Backbone.View.extend({ tagName: "li", className: "document", render: function() { // ... } }); ~~~ ### template方法 視圖的template屬性用來指定網頁模板。 ~~~ var AppView = Backbone.View.extend({ template: _.template("<h3>Hello <%= who %><h3>"), }); ~~~ 上面代碼中,underscore函數庫的template函數,接受一個模板字符串作為參數,返回對應的模板函數。有了這個模板函數,只要提供具體的值,就能生成網頁代碼。 ~~~ var AppView = Backbone.View.extend({ el: $('#container'), template: _.template("<h3>Hello <%= who %><h3>"), initialize: function(){ this.render(); }, render: function(){ this.$el.html(this.template({who: 'world!'})); } }); ~~~ 上面代碼的render就調用了template方法,從而生成具體的網頁代碼。 實際應用中,一般將模板放在script標簽中,為了防止瀏覽器按照JavaScript代碼解析,type屬性設為text/template。 ~~~ <script type="text/template" data-name="templateName"> <!-- template contents goes here --> </script> ~~~ 可以使用下面的代碼編譯模板。 ~~~ window.templates = {}; var $sources = $('script[type="text/template"]'); $sources.each(function(index, el) { var $el = $(el); templates[$el.data('name')] = _.template($el.html()); }); ~~~ ### events屬性 events屬性用于指定視圖的事件及其對應的處理函數。 ~~~ var Document = Backbone.View.extend({ events: { "click .icon": "open", "click .button.edit": "openEditDialog", "click .button.delete": "destroy" } }); ~~~ 上面代碼中一個指定了三個CSS選擇器的單擊事件,及其對應的三個處理函數。 ### listento方法 listento方法用于為特定事件指定回調函數。 ~~~ var Document = Backbone.View.extend({ initialize: function() { this.listenTo(this.model, "change", this.render); } }); ~~~ 上面代碼為model的change事件,指定了回調函數為render。 ### remove方法 remove方法用于移除一個視圖。 ~~~ updateView: function() { view.remove(); view.render(); }; ~~~ ### 子視圖(subview) 在父視圖中可以調用子視圖。下面就是一種寫法。 ~~~ render : function (){ this.$el.html(this.template()); this.child = new Child(); this.child.appendTo($.('.container-placeholder').render(); } ~~~ ## Backbone.Router Router是Backbone提供的路由對象,用來將用戶請求的網址與后端的處理函數一一對應。 首先,新定義一個Router類。 ~~~ Router = Backbone.Router.extend({ routes: { } }); ~~~ ## routes屬性 Backbone.Router對象中,最重要的就是routes屬性。它用來設置路徑的處理方法。 routes屬性是一個對象,它的每個成員就代表一個路徑處理規則,鍵名為路徑規則,鍵值為處理方法。 如果鍵名為空字符串,就代表根路徑。 ~~~ routes: { '': 'phonesIndex', }, phonesIndex: function () { new PhonesIndexView({ el: 'section#main' }); } ~~~ 星號代表任意路徑,可以設置路徑參數,捕獲具體的路徑值。 ~~~ var AppRouter = Backbone.Router.extend({ routes: { "*actions": "defaultRoute" } }); var app_router = new AppRouter; app_router.on('route:defaultRoute', function(actions) { console.log(actions); }) ~~~ 上面代碼中,根路徑后面的參數,都會被捕獲,傳入回調函數。 路徑規則的寫法。 ~~~ var myrouter = Backbone.Router.extend({ routes: { "help": "help", "search/:query": "search" }, help: function() { ... }, search: function(query) { ... } }); routes: { "help/:page": "help", "download/*path": "download", "folder/:name": "openFolder", "folder/:name-:mode": "openFolder" } router.on("route:help", function(page) { ... }); ~~~ ## Backbone.history 設置了router以后,就可以啟動應用程序。Backbone.history對象用來監控url的變化。 ~~~ App = new Router(); $(document).ready(function () { Backbone.history.start({ pushState: true }); }); ~~~ 打開pushState方法。如果應用程序不在根目錄,就需要指定根目錄。 ~~~ Backbone.history.start({pushState: true, root: "/public/search/"}) ~~~ ## Backbone.Model Model代表單個的對象實體。 ~~~ var User = Backbone.Model.extend({ defaults: { name: '', email: '' } }); var user = new User(); ~~~ 上面代碼使用extend方法,生成了一個User類,它代表model的模板。然后,使用new命令,生成一個Model的實例。defaults屬性用來設置默認屬性,上面代碼表示user對象默認有name和email兩個屬性,它們的值都等于空字符串。 生成實例時,可以提供各個屬性的具體值。 ~~~ var user = new User ({ id: 1, name: 'name', email: 'name@email.com' }); ~~~ 上面代碼在生成實例時,提供了各個屬性的具體值。 ### idAttribute屬性 Model實例必須有一個屬性,作為區分其他實例的主鍵。這個屬性的名稱,由idAttribute屬性設定,一般是設為id。 ~~~ var Music = Backbone.Model.extend({ idAttribute: 'id' }); ~~~ ### get方法 get方法用于返回Model實例的某個屬性的值。 ~~~ var user = new User({ name: "name", age: 24}); var age = user.get("age"); // 24 var name = user.get("name"); // "name" ~~~ ### set方法 set方法用于設置Model實例的某個屬性的值。 ~~~ var User = Backbone.Model.extend({ buy: function(newCarsName){ this.set({car: newCarsName }); } }); var user = new User({name: 'BMW',model:'i8',type:'car'}); user.buy('Porsche'); var car = user.get("car"); // ‘Porsche’ ~~~ ### on方法 on方法用于監聽對象的變化。 ~~~ var user = new User({name: 'BMW',model:'i8'}); user.on("change:name", function(model){ var name = model.get("name"); // "Porsche" console.log("Changed my car’s name to " + name); }); user.set({name: 'Porsche'}); // Changed my car’s name to Porsche ~~~ 上面代碼中的on方法用于監聽事件,“change:name”表示name屬性發生變化。 ### urlroot屬性 該屬性用于指定服務器端對model進行操作的路徑。 ~~~ var User = Backbone.Model.extend({ urlRoot: '/user' }); ~~~ 上面代碼指定,服務器對應該Model的路徑為/user。 ### fetch事件 fetch事件用于從服務器取出Model。 ~~~ var user = new User ({id: 1}); user.fetch({ success: function (user){ console.log(user.toJSON()); } }) ~~~ 上面代碼中,user實例含有id屬性(值為1),fetch方法使用HTTP動詞GET,向網址“/user/1”發出請求,從服務器取出該實例。 ### save方法 save方法用于通知服務器新建或更新Model。 如果一個Model實例不含有id屬性,則save方法將使用POST方法新建該實例。 ~~~ var User = Backbone.Model.extend({ urlRoot: '/user' }); var user = new User (); var userDetails = { name: 'name', email: 'name@email.com' }; user.save(userDetails, { success: function (user) { console.log(user.toJSON()); } }) ~~~ 上面代碼先在類中指定Model對應的網址是/user,然后新建一個實例,最后調用save方法。它有兩個參數,第一個是實例對象的具體屬性,第二個參數是一個回調函數對象,設定success事件(保存成功)的回調函數。具體來說,save方法會向/user發出一個POST請求,并將{name: 'name', email: '[name@email.com](mailto:name@email.com)'}作為數據提供。 如果一個Model實例含有id屬性,則save方法將使用PUT方法更新該實例。 ~~~ var user = new User ({ id: 1, name: '張三', email: 'name@email.com' }); user.save({name: '李四'}, { success: function (model) { console.log(user.toJSON()); } }); ~~~ 上面代碼中,對象實例含有id屬性(值為1),save將使用PUT方法向網址“/user/1”發出請求,從而更新該實例。 ### destroy方法 destroy方法用于在服務器上刪除該實例。 ~~~ var user = new User ({ id: 1, name: 'name', email: 'name@email.com' }); user.destroy({ success: function () { console.log('Destroyed'); } }); ~~~ 上面代碼的destroy方法,將使用HTTP動詞DELETE,向網址“/user/1”發出請求,刪除對應的Model實例。 ## Backbone.Collection Collection是同一類Model的集合,比如Model是動物,Collection就是動物園;Model是單個的人,Collection就是一家公司。 ~~~ var Song = Backbone.Model.extend({}); var Album = Backbone.Collection.extend({ model: Song }); ~~~ 上面代碼中,Song是Model,Album是Collection,而且Album有一個model屬性等于Song,因此表明Album是Song的集合。 ### add方法,remove方法 Model的實例可以直接放入Collection的實例,也可以用add方法添加。 ~~~ var song1 = new Song({ id: 1 ,name: "歌名1", artist: "張三" }); var song2 = new Music ({id: 2,name: "歌名2", artist: "李四" }); var myAlbum = new Album([song1, song2]); var song3 = new Music({ id: 3, name: "歌名3",artist:"趙五" }); myAlbum.add(song3); ~~~ remove方法用于從Collection實例中移除一個Model實例。 ~~~ myAlbum.remove(1); ~~~ 上面代碼表明,remove方法的參數是model實例的id屬性。 ### get方法,set方法 get方法用于從Collection中獲取指定id的Model實例。 ~~~ myAlbum.get(2)) ~~~ ### fetch方法 fetch方法用于從服務器取出Collection數據。 ~~~ var songs = new Backbone.Collection; songs.url = '/songs'; songs.fetch(); ~~~ ## Backbone.events ~~~ var obj = {}; _.extend(obj, Backbone.Events); obj.on("show-message", function(msg) { $('#display').text(msg); }); obj.trigger("show-message", "Hello World"); ~~~ ## 參考鏈接 * Andy Walpole,?[2015: The End of the Monolithic JavaScript Framework](https://andywalpole.me/#!/blog/142134/2015-the-end-the-monolithic-javascript-framework) * Biswadeep Ghosh,?[Introduction to Backbone.js](http://www.phloxblog.in/introduction-backbone-js/)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看