您現在的位置是:電腦技術吧?>? 故障問題 ??>??ios使用技巧,蘋果使用技巧??>??正文詳情

ios使用技巧,蘋果使用技巧

江安宜2019-12-16 17:42:09 人圍觀
簡介s檔使用技巧這篇文章主要介紹了Backbone.js的一些使用技巧,Backbone.js是一款人氣JavaScript庫,需要的朋友可以參考下 自從3年前Backbon蘋果x全部使用技巧圖解

這篇文章主要介紹了Backbone.js的一些使用技巧,Backbone.js是一款人氣JavaScript庫,需要的朋友可以參考下  自從3年前Backbone.js發布第一版以來,Backbone.js就成為一個流行的開源JavaScript MV*框架,并獲得人們的青睞。

盡管Backbone.js給JavaScript應用提供了框架,但是它仍然給開發者留有很多設計模式供選擇,不管怎樣,當開發者第一次使用Backbone.js時還會產生很多普遍的問題的。

  因此,在這篇文章中,我們將介紹很多不同的設計模式供你在Backbone.js應用中使用,而且我們也會一同來看看對于開發者來說會產生很多普遍的有關性能伸縮的問題。

  對象深度拷貝  JavaScript對待所有原生類型變量是傳值。

所以,當變量被引用時就傳遞了變量的值。

  ? 1 2 var helloWorld = Hello World; var helloWorldCopy = helloWorld;   舉個例子,上面的代碼將變量helloWorldCopy的值設置為變量helloWorld的值。

這樣, 自從它的值被復制之后,所有修改helloWorldCopy的值不會修改helloWorld的值。

JavaScript對待所有非原始類型的變量時傳引用,這就意味著當變量傳遞的時候將會傳遞內存地址引用。

  ? 1 2 3 4 var helloWorld = { hello': world' } var helloWorldCopy = helloWorld;   舉個例子,上面的代碼將設置helloWorldCopy為helloWorld的引用,而且,也許你會猜到任何修改helooWorldCopy的值都會直接導致helloWorld值的變化。

如果你想要helloWorld的拷貝,你可以創建一個拷貝對象即可。

  也許你會想到為什么Backbone.js可以解釋為所有的工作都是通過傳遞引用?事實上,Backbone.js不會拷貝對象,這將意味著如果你從模型里調用.get()方法獲得一個對象,任何給這個對象的修改都會直接修改原來的對象。

讓我們一起來看一個例子來闡明哪里會發生這樣的情況。

如果你有個如下的Person模型:  ? 1 2 3 4 5 6 7 8 9 10 11 var Person = Backbone.Model.extend({ defaults: { 'name': 'John Doe', 'address': { 'street': '1st Street' 'city': 'Austin', 'state': 'TX' 'zipCode': 78701 } } });   這樣你就創建了一個新的person對象:  ? 1 2 3 var person = new Person({ 'name': 'Phillip W' });   現在我們來對新對象的一些屬性進行操作操作:  person.set('name', 'Phillip W.', { validate: true });  上面的代碼成功的給person對象的name屬性賦了值。

現在我們在來操作person對象的地址屬性。

當然,在我們這樣做之前先驗證一下地址屬性。

  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 var Person = Backbone.Model.extend({ validate: function(attributes) { if(isNaN(attributes.address.zipCode)) return Address ZIP code must be a number!; }, defaults: { 'name': 'John Doe', 'address': { 'street': '1st Street' 'city': 'Austin', 'state': 'TX' 'zipCode': 78701 } } });   現在,讓我們試圖給地址屬性設置一個不正確的ZIP代碼。

  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 var address = person.get('address'); address.zipCode = 'Hello World'; // Raises an error since the ZIP code is invalid person.set('address', address, { validate: true }); console.log(person.get('address')); /* Prints an object with these properties. { 'street': '1st Street' 'city': 'Austin', 'state': 'TX' 'zipCode': 'Hello World' } */   這將會怎樣呢?我們的驗證出現了錯誤!為什么屬性依舊被改變了?前邊我們說過,Backbone.js不會拷貝模型屬性;它會返回你所請求的一切。

這樣,你也許會猜到,如果你需要一個對象,你將得到這個對象的引用,對這個對象的任何操作都會直接改變模型里的對象。

如果你要debug,這可能將把你帶入到無底的兔子黑洞。

  這個問題對于新的Backbone.js使用要引起注意,甚至對于老練的JavaScript程序員有時也會沒有提防。

這個問題在GitHub的Backbone.js討論組中有很激烈的討論。

正如Jeremy Ashkenas指出,執行一個深的對象引用是個很難解決的難題,一個很深的對象引用是要花費很大代價的。

  幸運的,jQuery 提供了一個深度拷貝功能來實現,$.extend. 如同, Underscore.js ,一個Backbone.js的依靠,提供_.extend 方法,但是我必須避免使用它,因為它沒有執行一份是個深度的復制,Lo-Dash, Underscore.js的一個分叉版本,提供了對象一個深度克隆的_.clone 方法的選項。

然而,我使用 $.extend 方法的模型使用的語法規則去執行一個任意對象的深度克隆。

記得通過后,結果它執行的是一個深度的克隆方法  ? 1 var address = $.extend(true, {}, person.address);   我們現在快速準確的復制一個theaddressobject?,并且我們能夠更改它對于我們要點沒有包括在內的我們不用擔心會更改它原有的模型。

你必須要意思到這個父工廠對于上面所有的事例因為它所有的地址對象成員都是不可變的(numbers, strings, etc.),與此同時這上面所有的事例工廠當你要深度復制對象里面包含的對象時你都必須小心的使用。

你必須也要知道一個小小的性能影響都來自于執行一個深度的克隆,但是我從來沒有看到過很明顯的問題。

然而,如果你要深度的克隆一個大對象或者成千上萬的對象所有的立即復制,你將有可能做大量的性能分析。

這將領導我們直接到下一個模式。

  為對象創建外觀  在現實世界中,需求經常變化,JavaScript對象符號(或者說JSON)也是一樣,這些對象是由模型和集合所在的端點返回的。

這或許會成為你的基礎代碼中的一個真正的大麻煩,如果你的視圖與底層的數據模型是緊耦合的話。

因此,我為所有對象創建了getters和setters。

  支持這個模式的人非常多。

如果任何底層的數據結構改變了,那么視圖層并不需要更新許多;你將有一個數據的訪問點,所以你不太可能忘記做一個深度拷貝,你的代碼將會更易于維護更易于調試。

負面因素在于這個模式可能導致模型或集合的一點點膨脹。

  我們看一個例子來闡明這個模式。

想像我們有一個Hotel模型,包含有rooms和目前可獲得的rooms,而且我們希望可以通過床位大小來獲得rooms。

  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 var Hotel = Backbone.Model.extend({ defaults: { availableRooms: [a], rooms: { a: { size: 1200, bed: queen }, b: { size: 900, bed: twin }, c: { size: 1100, bed: twin } }, getRooms: function() { $.extend(true, {}, this.get(rooms)); }, getRoomsByBed: function(bed) { return _.where(this.getRooms(), { bed: bed }); } } });   現在我們假設明天你就要發布你的代碼,而你又發現端點開發者忘記告訴你rooms的數據結構改變了,由一個對象變為一個數組。

你的代碼現在看起來會像下面這樣。

  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 var Hotel = Backbone.Model.extend({ defaults: { availableRooms: [a], rooms: [ { name: a, size: 1200, bed: queen }, { name: b, size: 900, bed: twin }, { name: c, size: 1100, bed: twin } ], getRooms: function() { var rooms = $.extend(true, {}, this.get(rooms)), newRooms = {}; // transform rooms from an array back into an object _.each(rooms, function(room) { newRooms[room.name] = { size: room.size, bed: room.bed } }); }, getRoomsByBed: function(bed) { return _.where(this.getRooms(), { bed: bed }); } } });   我們僅僅更新了一個函數,以便將Hotel的結構轉變為這個應用的其余部分所期望的結構,同時整個應用仍然像我們所期待的一樣運作。

如果這里沒有一個getter,我們很可能不得不為rooms更新每個訪問點。

理想情況下,你會希望更新所有的函數,以適應新的數據結構,但如果你在時間方面有壓力急于發布的話,這個模式將可以拯救你。

  離題說一句,這個模式既可以被認為是裝飾模式,因為它隱藏了創建對象拷貝的復雜性,也可以認為是橋接模式,因為它可以用來將數據轉換為所期望的形式。

一個好的經驗是對任何對象元素使用getters 和setters 。

  存儲數據不是通過服務器保存  盡管Backbone.js有模型和集合映射的規定去具象狀態的傳輸(or REST-ful)的端點,你將花大量的時間去找你想要的存儲數據在你的模型或者不是在服務器上的連接。

另外一些關于Backbone.js的文章,例如Backbone.js Tips: Lessons From the Trenches 是通過SupportBee的Prateek Dayal ,這個模式還有其他的描述。

讓我們一起來快速的看一個小例子來幫助我們說明它可能會派上用場。

假設你有一個集合。

  ? 1 2 3 4 5 6 ul lia href=# data-id=1One/a/li lia href=# data-id=2Two/a/li . . . lia href=# data-id=nn/a/li /ul   當使用者點擊其中一個項目時,這個項目成為了被選中狀態并且對于使用者作為選中項目是通過 aselectedclass 添加的是可視化的。

以下這是一種方式:  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 var Model = Backbone.Model.extend({ defaults: { items: [ { name: One, id: 1 }, { name: Two, id: 2 }, { name: Three, id: 3 } ] } }); var View = Backbone.View.extend({ template: _.template($('#list-template').html()), events: { #items li a: setSelectedItem }, render: function() { $(this.el).html(this.template(this.model.toJSON())); }, setSelectedItem: function(event) { var selectedItem = $(event.currentTarget); // Set all of the items to not have the selected class $('#items li a').removeClass('selected'); selectedItem.addClass('selected'); return false; } }); script id=list-template type=template ul id=items % for(i = items.length - 1; i = 0; i--) { % li a href=# data-id=%= item[i].id %%= item[i].name %/a/li % } %/ul /script   現在我們能夠很容易的判斷被選中的項目,并且我們沒有必要通過對象模型去判斷。

這種模式對于存儲無用的數據是非常有用的以至于 你可能非常想要去跟蹤;請記住你能夠創建一個模型并且沒有必要去關聯于他們存儲的一些無用的圖像數據。

  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 var View = Backbone.View.extend({ initialize: function(options) { // Re-render when the model changes this.model.on('change:items', this.render, this); }, template: _.template($('#list-template').html()), events: { #items li a: setSelectedItem }, render: function() { $(this.el).html(this.template(this.model.toJSON())); }, setSelectedItem: function(event) { var selectedItem = $(event.currentTarget); // Set all of the items to not have the selected class $('#items li a').removeClass('selected'); selectedItem.addClass('selected'); // Store a reference to what item was selected this.selectedItemId = selectedItem.data('id')); return false; } });   現在我們可以很容易的確定哪些項已經被選中,并且我們沒有必要通過這些對象模型來了解。

這個模式對于存儲無用的數據是非常有用的,請記住,您可以創建不一定有端點相關聯的存儲無關的視圖數據的模型和集合。

  這種模式的缺點是你存儲了無用的數據在你的模型或者集合中,它們不能真正意義上的追隨一個平靜的架構是因為它們不會完美的去映射在web資源上;另外,這個模式會引起一些很膨脹的在你的模型中;;并且當你保存你的模型的時候如果你的端點嚴格的只接受JSON數據它會引起一個很大的煩惱。

  你可能會問你自己,我如何確定我是否應該講把額外的數據放進視圖或者是模型中?。

如果額外的屬性你將要增加的是圍繞性的呈現,例如一個容器的高度,我們應該要添加它的圖形。

如果這個屬性跟底層的數據模型有一些關系,然后你想要將它放進這個模型中。

例如,如果上面的例子更多的顯露出,因為某些原因我僅僅只希望用戶通過從模型返回的項目列表中選擇一個特殊的項,我可能會增加這種邏輯模型。

總而言之,大多數的事情,它實際上取決于這種依賴。

你能夠為保持你的模型而辯論并且你可以認為保持你的觀點是可能的并且把盡可能多的邏輯放進你的模型中。

  渲染部分視圖,而不是整個視圖  當你第一次開始開發Backbone.js應用時,典型的視圖結構是像這樣的:  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 var View = Backbone.View.extend({ initialize: function(options) { this.model.on('change', this.render, this); }, template: _.template($(#template').html()), render: function() { this.$el.html(template(this.model.toJSON()); $(#a', this.$el).html(this.model.get(a')); $(#b', this.$el).html(this.model.get(b')); } });   在這里,任何對模型的改變都會觸發對視圖的一個全面的重新渲染。

我第一次用Backbone.js開發時,我是這個模式的實踐者。

但隨著視圖代碼的增長,我迅速的意識到,這種方法不利于維護或優化,因為當模型的任何一個屬性發生變化時,視圖將會完全的重新渲染。

  當我遇到這個問題,我迅速的用Google搜索了一下,看看別人是怎么做的,結果找到了Ian Storm Taylor的博客,分解你的Backbone.js渲染方法,他在其中描述了在模型中監聽單獨的屬性變化,然后僅僅重新渲染相對于變化屬性的視圖部分。

Taylor也描述了返回對象的引用,以便單獨的渲染函數可以很容易的鏈接在一起。

上面的例子現在現在就變得更易于維護,性能更優。

因為我們僅僅更新了模型變化的屬性相對應的視圖部分。

  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 var View = Backbone.View.extend({ initialize: function(options) { this.model.on('change:a', this.renderA, this); this.model.on('change:b', this.renderB, this); }, renderA: function() { $(#a', this.$el).html(this.model.get(a')); return this; }, renderB: function() { $(#b', this.$el).html(this.model.get(b')); return this; }, render: function() { this .renderA() .renderB(); } });   我應該說一下有許多插件,比如Backbone.StickIt和Backbone.ModelBinder,提供了模型屬性與視圖元素的鍵-值綁定,這會讓你省去編寫許多樣板代碼,如果你具有復雜的表單字段檢驗一下它們。

  保持模型與視圖無關  正如 Jeremy Ashkenas 在 Backbone.js的 GitHub問題 之一中所指出的,Backbone.js 并沒有實施數據與視圖層之間關注點的任何真正分離,除非模型未引用視圖而創建。

因為Backbone.js并沒有執行一個關注點分離,所以你應該將其分離嗎?我和許多其他的Backbone.js開發人員,如Oz Katz 和 Dayal ,都相信答案毫無疑問是yes:模型與集合,也就是數據層,應該徹底的與綁定到它們的視圖無關,保持一個清晰的關注點分離。

如果你沒有遵循關注點分離,你的基礎代碼將很快變成意大利面條式的代碼,而沒有人喜歡意大利面條式的代碼。

  保持模型與視圖無關將會幫助你預防意大利面條式的代碼,而沒有人喜歡意大利面條式的代碼!  保持你的數據層徹底的與視圖層無關,這將會使你創建出更具模塊化,可復用與可維護的基礎代碼。

你可以非常容易的在應用程序各個地方復用與擴展模型和集合,而不需要考慮它們所綁定的視圖。

遵循這個模式使對你項目不熟悉的開發者能迅速的深入到基礎代碼之中,因為他們會確切的知道哪里發生了渲染,哪里存在有你的應用的所有商務邏輯。

  這個模式也執行了單一職責原則,規定了每個類應該具有一個單一的職責,而且它的職責應該封裝與這個類之中,因為模型與集合要處理數據,而視圖要處理渲染。

  路由中的參數  最好的演示這個模式工作方式是舉個例子。

比如說你需要對搜索頁面進行排序,每個搜索頁面都允許用戶添加兩個不同的過濾類型foo和bar,每個類型代表不同的觀點。

  因此,你的URL結構將會呈現如下:  ? 1 2 3 'search/:foo' 'search/:bar' 'search/:foo/:bar'   現在,所有的路由都用的是同一個試圖和模型,這樣大多數人喜歡用同一個函數search()來實現。

然而,你要是檢查過Backbone.js代碼的話,你會發祥它里面沒有排序的參數映射;這些參數只是從左至右依次傳入函數。

這樣,為了都能統一使用一個函數,你就要停止創建不同的函數正確的來為search()匹配參數。

  ? 1 routes: { 'search/:foo': 'searchFoo', 'search/:bar': 'searchBar', 'search/:foo/:bar': 'search' }, search: function(foo, bar) { }, // I know this function will actually still map correctly, but for explanatory purposes, it's left in. searchFoo: function(foo) { this.search(foo, undefined); }, searchBar: function(bar) { this.search(undefined, bar); },   你也許能想象的到,這個模式可以使路由功能很快膨脹。

當我第一次遇到這個問題時,我試圖創建了一些用正則表達式定義的解析函數來神奇的去匹配參數,當然這個是可以工作的-但這也是有約束條件的。

這樣,我廢棄了這個想法(有時,我仍然可以用Backbone插件來解決)。

我進入GitHub中的一個 議題,其中Ashkenas建議應該讓所有的參數都和search函數匹配。

  上面的代碼現在轉變為下面維護性更強的樣子:  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 routes: { 'search/:foo': 'searchFoo', 'search/:bar': 'searchBar', 'search/:foo/:bar': 'search' }, search: function(foo, bar) { }, // I know this function will actually still map correctly, but for explanatory purposes, it's left in. searchFoo: function(foo) { this.search(foo, undefined); }, searchBar: function(bar) { this.search(undefined, bar); },   這種模式可以戲劇性的減少路由的過分膨脹。

然而,需要注意到它不會服務于不能區別的參數。

比如,如果你有兩個作為ID的參數,如模式XXXX-XXXX,你不能區分哪個ID是對哪個參數的回應。

  model.fetch() 不會清除你的模型  這通常會將那些Backbone.js的新手給絆倒:model.fetch()并不能丟掉你的模型,而是擴展了你的模型的屬性。

因此,如果你的模型具有屬性x,y和z,你獲取到y和z,那么x將仍然是模型中的那個x,只有y和z會被更新。

下面的例子將這個概念形象化了。

  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 var Model = Backbone.Model.extend({ defaults: { x: 1, y: 1, z: 1 } }); var model = new Model(); /* model.attributes yields { x: 1, y: 1, z: 1 } */ model.fetch(); /* let's assume that the endpoint returns this { y: 2, z: 2, } */ /* model.attributes now yields { x: 1, y: 2, z: 2 } */   PUTs 需要一個 ID 屬性  這一條也經常將Backbone.js的新手絆倒。

要想在調用.save()的時候讓模型發送一個HTTP PUT請求,你的模型需要有一個ID屬性集。

記得HTTP PUT謂詞是設計來做更新的吧,所以發送一個PUT請求,你的模型需要有一個ID,這么做是有意義的。

在理想的世界里,你的所有模型都具有一個名為ID的完美的ID屬性,但是你從端點接收到的JSON數據可能并不總是具有完美命名的IDs。

  因此,如果你需要更新一個模型,請在保存之前確認模型上有ID。

Backbone.js 的0.5以及更高版本允許你用id屬性來更新模型的ID屬性名稱,如果你的端點返回的不是名為id的IDs的話。

  如果困頓于使用的是版本低于0.5的Backbone.js,我建議你修改你的模型或集合的parse函數,以便將你期望的ID屬性映射到屬性ID。

這里有一個快速上手的例子,說明了你應怎樣修改parse函數來做到這一點。

我們假設你有一個cars的集合,它的IDs是carID。

  ? 1 2 3 4 5 6 7 8 9 parse: function(response) { _.each(response.cars, function(car, i) { // map the returned ID of carID to the correct attribute ID response.cars[i].id = response.cars[i].carID; }); return response; },   頁面加載時創建模型數據  有時你會發現你的模型或者集合需要在頁面加載時被初始化賦值。

許多關于Backbone.js模式的文章,例如Rico Sta Cruz的 Backbone 模式 和 Katz的 避免常見的Backbone.js陷阱 ,討論了這種模式。

這種模式實現很容易,只需在頁面中內聯一段腳本,通過你選擇的服務端語言,將單個模型屬性或者JSON形式的數據呈現出來。

例如,在Rails語言中,我采用下面方法之一:  ? 1 2 3 4 5 6 // a single attribute var model = new Model({ hello: %= @world % }); // or to have json var model = new Model(%= @hello_world.to_json %);   應用這種模式可以通過立即的渲染頁面,改善你的搜索引擎排名,而且它也可以通過限制應用初始化HTTP請求的方式,大大縮短你的應用啟動與運行所需要的時間。

  處理失敗的模型屬性驗證  很多時候,你會想知道是哪個模型屬性驗證失敗了。

例如,如果你有一個極其復雜的表單,你或許想知道哪個模型屬性驗證失敗,這樣你就可以將這個屬性對應的輸入字段高亮顯示。

不幸的是,提醒視圖到底是哪個模型屬性驗證失敗并沒有直接集成于Backbone.js,但是你可以用一些不同的模式去處理這個問題。

  返回一個錯誤對象  一個給視圖提醒哪個模型屬性驗證失敗的模式是,返回一個對象,其中包含某種標志,它詳細的記錄了哪個屬性驗證為失敗,就像下面這樣:  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 // Inside your model validate: function(attrs) { var errors = []; if(attrs.a 0) { errors.push({ 'message': 'Form field a is messed up!', 'class': 'a' }); } if(attrs.b 0) { errors.push({ 'message': 'Form field b is messed up!', 'class': 'b' }); } if(errors.length) { return errors; } } // Inside your view this.model.on('invalid', function(model, errors) { _.each(errors, function(error, i) { $(.' error.class).addClass('error'); alert(error.message); }); });   這個模式的優點在于,你是在一個地方處理所有不合法的消息。

缺點在于,如果你以不同的方式處理不合法的屬性的話,你的invalid方法可能會成為一個很大的switch或者if語句。

  廣播自定義Error事件  我的一個朋友,Derick Bailey,推薦了一個可替代模式,就是為每個模型屬性觸發自定義的errors事件。

這將允許你的視圖能夠針對單獨的屬性綁定到特定的error事件:  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // Inside your model validate: function(attrs) { if(attrs.a 0) { this.trigger(invalid:a', 'Form field a is messed up!', this); } if(attrs.b 0) { this.trigger(invalid:b', 'Form field b is messed up!', this); } } // Inside your view this.model.on('invalid:a', function(error) { $(a').addClass('error'); alert(error); }); this.model.on('invalid:b', function(error) { $(b').addClass('error'); alert(error); });   這個模式的優點在于,你的視圖明確的綁定到它們所綁定到的error類型,而且如果你對每一種屬性error有特定的指令的話,它可以清理你的視圖部分代碼,使之更易于維護。

這個模式的一個不好的地方在于,如果在你處理不同的屬性error時并沒有太多的不同的話,你的視圖可能會變得極為膨脹。

  這兩種模式都有其利弊,你應該考慮清楚哪個模式對你的應用案例是最優的。

如果你按照同樣的方式處理所有失敗的驗證,那么第一個方法可能是最好的;如果你對每個模型屬性有特定的UI變化,那么后一種方法更好。

  HTTP狀態代碼200所觸發的錯誤  如果你的瀏覽器端模型或者集合收到了無效的JSON,盡管HTTP的狀態代碼是200,但瀏覽器端依然會觸發一個錯誤事件。

這種事件常發生于本地模擬JSON數據造成的。

那么,一個好的方法就是讀取經過 JSON 驗證器驗證了的模擬JSON數據文件。

或者從你的IDE獲得相應的 插件來及時獲取格式錯誤的JSON信息。

  創建一個一般性錯誤顯示模式  創建一個常見錯誤顯示代碼可以節省你的時間以及創建一個統一的模式來處理、可視化錯誤信息,而且它可以增加開發者的經驗。

我之前開發的每一個Backbone.js應用中我都會創建一個可以處理alert的視圖:  ? 1 2 3 4 5 6 7 8 9 10 11 12 var AlertView = Backbone.View.extend({ set: function(typeOfError, message) { var alert = $(.in-page-alert').length ? $(.in-page-alert'): $(.body-alert'); alert .removeClass(error success warning') .addClass(typeOfError) .html(message) .fadeIn() .delay(5000) .fadeOut(); } });   上面的代碼首先會檢查是否已在視圖代碼中創建了指定視圖in-page-alert div。

如果沒有,則接著查看一般性的在其它地方聲明的body-alert div。

這樣可以讓你發送具有一致性的錯誤信息以及當你忘記指定一個in-page-alert div時提供有用且可靠的信息。

如下面的模式簡化了讓你怎樣在你的試圖中處理錯誤信息:  ? 1 2 3 4 5 var alert = new AlertView(); this.model.on('error', function(model, error) { alert.set('TYPE-OF-ERROR', error); });   單頁面應用中更新瀏覽器頁面標題  這是一個比任何東西都重要的可用性問題。

如果你正在開發一個單頁面應用程序,謹記更新每個頁面的標題。

我寫過一個的插件(Backbone.js Router Title Helper)來擴展 backbone.js router 的功能。

它通過一個 Map 對象來控制路由,鍵來代表路由函數的名字,值則映射到頁面的標題。

  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Backbone.Router = Backbone.Router.extend({ initialize: function(options){ var that = this; this.on('route', function(router, route, params) { if(that.titles) { if(that.titles[router]) document.title = that.titles[router]; else if(that.titles.default) document.title = that.titles.default; else throw 'Backbone.js Router Title Helper: No title found for route:' router ' and no default route specified.'; } }); } });   單頁面應用中的緩存對象  當我們談論單頁面應用時,另一個叫緩存對象模式你將會經常用到!下面的例子直截了當而且簡單:  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // Inside a router initialize: function() { this.cached = { view: undefined, model: undefined } }, index: function(parameter) { this.cached.model = this.cached.model || new Model({ parameter: parameter }); this.cached.view = this.cached.view || new View({ model: this.cached.model }); }   這個模式可以加速你得應用,因為你不用重復初始化你得Backbone.js對象。

然而,它會過多的消耗內存;所以,緩存對象就要在整個應用中使用。

如果以前你用過Backbone.js開發過應用,也許你會問你自己, 我要重取數據該怎么做?你可以每次在如下路徑中觸發后重取數據:  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // Inside a router initialize: function() { this.cached = { view: undefined, model: undefined } }, index: function(parameter) { this.cached.model = this.cached.model || new Model({ parameter: parameter }); this.cached.view = this.cached.view || new View({ model: this.cached.model }); this.cached.model.fetch(); }   當你的應用從端點(如,一個收件箱)必須檢索最新數據時上面的模式就可以工作。

當然,如果你要拿的數據時憑借應用的某個狀態(假設這個狀態是通過URL和參數來決定的),甚至是在用戶上一個頁面應用的狀態沒有改變, 你可以重取數據。

一個好的解決方案去重拿數據時當應用(參數)發生變化時:  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // Inside a router initialize: function() { this.cached = { view: undefined, model: undefined } }, index: function(parameter) { this.cached.model = this.cached.model || new Model({ parameter:parameter }); this.cached.model.set('parameter', parameter); this.cached.view = this.cached.view || new View({ model: this.cached.model }); } // Inside of the model initialize: function() { this.on(change:parameter, this.fetchData, this); }   JSDoc函數和Backbone.js類  我是文檔注釋和JSDoc的超級粉絲。

我用JSDoc對所有的Backbone類添加了文檔注釋:  ? 1 2 3 4 5 6 7 8 9 10 11 12 var Thing = Backbone.View.extend(/** @lends Thing.prototype */{ /** @class Thing * @author Phillip Whisenhunt * @augments Backbone.View * @contructs Thing object */ initialize() {}, /** Gets data by ID from the thing. If the thing doesn't have data based on the ID, an empty string is returned. * @param {String} id The id of get data for. * @return {String} The data. */ getDataById: function(id) {} });   如果你對Backbone類進行如上添加文檔注釋,這樣你可以給所有類和函數 添加參數、返回類型以及描述文檔注釋了。

確保保持初始化函數作為一個聲明的函數,這樣可以幫助我們生成JSDoc。

如果你想看看JSDoc的例子工程,那就在 HomeAway Calendar Widget下載例子。

同時這里也有個 Grunt.js插件, grunt-jsdoc-plugin,這個也可以作為你構建文檔注釋時的一部分。

  聯系測試驅動的開發模式  我認為如果你用Backbone.js,你應該在開發模型和集合時遵循測試驅動開發(TDD)。

我第一次用Jasmine.js創建模型和集合時遵循TDD進行單元測試,但失敗了。

一旦寫下單元測試并且失敗,我會對整個模型和集合進行重寫。

  通過這一點,我的所有Jasmine測試都通過了,而且我有信心我的模型和集合會和我期望的一樣工作。

自從我遵循TDD,我的視圖層非常容易寫而且非常簡單。

當你開始用TDD時,你得速度當然會很慢;但是一但你得腦海里一直想著TDD,你的編程效率和質量會神奇般的提高。

版權聲明:本文由 江安宜 整理編輯。

原標題:蘋果6使用技巧,m檔位怎么使用技巧

轉載注明出處:http://www.dn9ww09s.icu/fault/15493.html

文章評論

    共有條評論來說兩句吧...

    用戶名:

    驗證碼:

作者推薦

  • iOS13支持設備,ios設備是什么

    iOS13支持設備,ios設備是什么 相關圖片ios設備是什么意思網絡上有很多iOS組件庫,很方便實現控件,所以綠茶小編提醒,此篇文章只是講訴下,要如何在 iOS 設備上呈現原型?  很多 UX 和 PM 同學還是習慣使用傳統ios設備在哪...

  • asp控件如何使用,asp控件添加

    asp控件如何使用,asp控件添加 相關圖片linkbutton控件本文主要介紹用自定義控件替換asp.net控件的方法。您可以為朋友參考以下函數:可以使用自定義控件頁的標記映射元素(asp.net設置體系結構)替換asp.negridview控件使用詳解...

  • java開發工具比較,Java可視化開發工具

    java開發工具比較,Java可視化開發工具 相關圖片java開發工具排行在計算機開發語言的歷史上,從來沒有一種語言能像Java那樣得到這么多廠商和開發工具的支持。誠然,這些工具有其自身的優勢,并非絕對完美。即使是老鳥也很難做出...

  • 交互原型是什么,網頁交互原型

    交互原型是什么,網頁交互原型 相關圖片產品交互原型圖許多用戶體驗和項目管理的學生仍然習慣于使用傳統的Axure RP制作產品原型。作者認為,Axure-RP在IOS原型階段仍然具有優勢,例如,它可以促進交互模式的在線交互原型...

  • asp 代碼,asp不用的代碼

    asp 代碼,asp不用的代碼 相關圖片asp時間代碼ASP語言是網站建設的重要工具之一,具有很強的技術性和適用性。ASP制作教程為您詳細介紹了部分代碼。一。Oncontextmenu=窗口。事件。ReturnVaasp時間輸入代碼...

  • 敲代碼用什么鍵盤,適合敲代碼的鍵盤

    敲代碼用什么鍵盤,適合敲代碼的鍵盤 相關圖片akko鍵盤怎么樣本文主要介紹了IOS對鍵盤色碼的修改,非常簡單實用。如果你需要的話,可以參考一下。IOS可以更改iPhone和iPod touch的鍵盤顏色代碼。實際上,iPh紅軸鍵盤...

  • Pregreplace,preg_replace空

    Pregreplace,preg_replace空 相關圖片數據庫replace函數本文的例子描述了PHP正則preg_replace_回調函數的使用。與您分享以供參考。具體實現方法如下:PHP正則表達式功能強大,本例演示preg﹣replacstr_replace關鍵詞替換...

  • 黑雷ios模擬器,ios安卓模擬器

    黑雷ios模擬器,ios安卓模擬器 相關圖片ios有電腦模擬器嗎IOS模擬器是一種輔助工具,可以在Mac環境下開發程序和IOS平臺程序。IOS模擬器是Xcode的一部分,Xcode是蘋果自己的IOS開發程序,可以免費下載!I電腦ios模擬器...

  • ios 動畫,ios新動畫

    ios 動畫,ios新動畫 相關圖片ios12動畫效果uiview類執行自動執行動畫所需的工作,但在您要執行動畫時仍會通知視圖,因此需要將更改屬性的代碼包裝成代碼塊。一。uiview動畫的特定創建方法-(void)ios10過渡動畫...

  • 不經過壓縮的圖像文件格式,用于壓縮靜止圖像

    不經過壓縮的圖像文件格式,用于壓縮靜止圖像 相關圖片如何壓縮jpg圖片在iPhone上讀取圖像數據有兩種簡單的方法:uiimagejpegresentation和uiimagepngrepresentation。uiImageJP壓縮頭像...

熱評文章

  • frm證書有用嗎,frm是什么證書

    frm證書有用嗎,frm是什么證書 相關圖片frm怎樣算通過有時候mysql沒有做好數據備份,或者被數據管理員誤刪,或者ibdata損壞了我們如何恢復呢?別怕,只要有部分frm、ibd存在,下面就是恢復教程。  mysqfrm等級...

  • guid分區表,具有mbr分區表

    guid分區表,具有mbr分區表 相關圖片磁盤分區表如果你的數據庫中某一個表中的數據滿足以下幾個條件,那么你就要考慮創建分區表了。  1、數據庫中某個表中的數據很多。很多是什么概念?一萬條?兩萬條?還是十萬條、...

  • 彩票開獎查詢排列5列5,彩票開獎查詢排列3

    彩票開獎查詢排列5列5,彩票開獎查詢排列3 相關圖片排列五歷史開獎結果前段時間客戶提出了一個需求,就是想讓查詢的結果隨機排序一下。查詢了很多東西說的很是不明白,最后解決了問題。方案如下:  只是在ORDER BY 后面加上一些...

  • java項目打包成jar包,web項目打包成jar包

    java項目打包成jar包,web項目打包成jar包 相關圖片eclipse打包成jar在做Android項目時,我們經常會遇到以下需求:將一些已經完成的項目集成到當前項目中,并以某種方式將以前項目的類和資源移動到當前項目中。接下來,我將介紹以前項...

  • iframe,if name==main

    iframe,if name==main 相關圖片if函數顯示name本文主要介紹if\\\\\\\\\\\\\\\\\\\\\\\\\\\__#name什么意思...

  • php文本寫入,php打開文件寫入內容

    php文本寫入,php打開文件寫入內容 相關圖片進入php怎么建文件本文的例子描述了如何在PHP中讀寫tab分隔的文件。與您分享以供參考。具體分析如下:該PHP代碼實現了對tab分離文件的讀寫,包括兩個獨立的函數,一個是讀寫,如p...

  • 怎樣添加控件,vs如何添加控件

    怎樣添加控件,vs如何添加控件 相關圖片如何添加文本框控件看到后臺有很多網頁,刪除內容時會有一個確認對話框,可以很好的避免意外刪除,所以我也想在我的asp.net項目中添加這個功能,研究一下,最后采取刪除確認的功...

  • SciPy入門指南,grails 入門指南

    SciPy入門指南,grails 入門指南 相關圖片php入門指南本文主要介紹JavaScript的requirejs庫的介紹指南。近年來,requirejs庫的普及程度迅速提高。您可以參考目前最常用的JavaScript庫之明日之后新手入門指南...

  • 應用程序大小,應用程序窗口大小調整

    應用程序大小,應用程序窗口大小調整 相關圖片縮小應用程序窗口問:如何使我的安裝包更小,下載和安裝程序更快?答:本文收集了一些關于減小安裝包大小的技巧(在第一次下載和安裝程序時)。如果是升級程序,您可以閱讀本...

  • oracle存儲過程是什么,oracle存儲過程詳解

    oracle存儲過程是什么,oracle存儲過程詳解 相關圖片oracle如何調用存儲過程如果不小心覆蓋了上一個存儲過程,則需要刷新。時間越長,閃回的可能性就越小。這是恢復原則。如果不小心覆蓋了上一個存儲過程,則需要刷新。時間越長,...

關注微信

变脸官网查询