2015-03-13 41 views
1

我正在使用Backbone.js。在我看來,我有一個textareakeyup勢必這樣的功能(以下但見編輯):當keyup觸發保存時保持光標位置的最佳做法

this.model.save({text: self.$('textarea').val()}, {patch: true}); 

在視圖中的initialize功能,我綁定模型的change事件視圖的render功能:

initialize: function() { 
    this.listenTo(this.model, 'change', _.bind(this.render, this)); 
}, 

麻煩的是,當在textarea用戶的類型,事件的下列順序發生:

  1. keyup事件觸發。
  2. 處理器在模型上調用save
  3. 致電save會觸發模型的模型的change事件。
  4. 該視圖,正在傾聽模型的change事件,請致電render
  5. textarea在DOM中被替換。
  6. textarea不再聚焦,文本光標位置丟失。

對於這樣的情況,texareakeyup事件需要觸發同步的最佳做法是什麼?我考慮過的一些選項:

  1. 不要綁定changerender。缺點:如果模型數據由於用戶輸入以外的其他因素而改變,textarea不會自動更新。
  2. 閱讀並記住在render開頭處的光標位置。將光標位置設置在render的末尾。缺點:取決於瀏覽器支持不明確的光標操作功能。
  3. keyup處理程序中,在視圖上設置一個臨時屬性,告訴它不要重新渲染。模型保存後取消設置。缺點:感覺像意大利麪代碼,與Backbone結構發生衝突。

我沒有看到任何選項嗎?你推薦以上選項之一嗎?

編輯

我不想從主點分散,但因爲它的答案中的一個上來:我沒有直接綁定到keyup,但_.debounce中介吧。因此,事件處理程序僅在用戶停止輸入時才運行,如自上次keyup以來經過一定時間所定義的那樣。

回答

1

首先我想勸阻這個,因爲看起來像是真的很奇怪的行爲,在keyup上保存你的模型。如果有一個真正需要的用例,我建議至少使用input事件 - 否則,每當用戶按下一個箭頭鍵,shift,ctrl等按鈕時,最終都會保存模型。

我認爲你也會想要消除輸入事件500毫秒左右,你實際上並沒有保存模型,每個單鍵擊。

爲了解決您的評論在第1點:

缺點:如果起因於 用戶輸入的任何其他模型數據的變化,textarea的不會自動更新

您需要去問問自己發生這種情況的可能性,以及如果這種情況發生,這種觀點被重新提出是多麼重要。

最後,如果你決定,這確實有可能這是很重要的觀點重新呈現,那麼你可以嘗試這樣的

http://jsfiddle.net/nuewwdmr/2/

的一個重要組成部分的東西在這裏是將模型屬性名稱映射到輸入的名稱字段。我在這裏所做的是遵循上述事件的順序。不同之處在於,當模型更改時,我們檢查已更改的屬性並更新模板中相應元素的值。

在一個非常簡單的情況下,這種工作正常,用戶在輸入中以「正常」方式鍵入的快樂路徑。例如,如果用戶決定返回到輸入的開頭並更改字母以使其大寫,則在模型中發生更改事件後,光標將跳轉到字符串的末尾。

您在這裏需要的行爲實際上是雙向的數據綁定,這絕不是微不足道的,特別是對於Backbone而言,給出了Backbone View具有的功能。

我的建議是你點1

不綁定的變化呈現

編輯

如果你想深入瞭解一下模型/視圖結合,你可以看看兩個庫:

stickit

epoxy

我以前用過stickit,它很好。不是很好。簡單的綁定就可以了,例如將「頂級」模型屬性綁定到輸入元素。一旦進入嵌套屬性,就會遇到問題,然後你必須研究諸如Backbone Deep Model之類的東西。

就像我說的,Backbone's View不提供很多。如果您有足夠的時間建議您使用React組件代替Backbone Views,或者查看一些ampersand必須提供的有趣內容。

+0

關於保存關鍵幀:我編輯了我的問題來澄清這一點。我已經在使用去抖動,所以顯然我同意你的建議。至於你答案的主要內容,我被你的推理說服了。我現在有信心,我不會反對Backbone的工作方式。謝謝! – rlkw1024 2015-03-14 13:28:59

+0

很高興聽到它。我已經用更多的信息更新了答案。 – garethdn 2015-03-14 17:19:09

相關問題