建立ViewModel
function ViewModel() { var self = this; self.hasOther = ko.observable(false); } ko.applyBindings(new ViewModel());hasOther表示checkbox是否被勾選
設定View的bindings
<label> <input type="checkbox" data-bind="checked: hasOther" />Others:</label> <input type="text" data-bind="enable: hasOther" />
checkbox裡用了checked binding,當checkbox被勾選時,ViewModel裡的hasOther會被更新成true
textbox裡則用了enable binding,當hasOther為true時,textbox就會被enabled。當然你也可以選擇用disable binding來實作。
到目前為止已達到需求的前半段 - 有勾選checkbox時,textbox才可以編輯,執行結果可參考http://jsfiddle.net/petekcchen/z4YJe/。
接下來實作後半段的需求 - checkbox被勾選的話,textbox要取得focus。看到focus,會想到hasfocus binding,只要將hasfocus binding設為hasOther,就可以達到當hasOther為true時,hasfocus也會是true,textbox就會有focus。OK,將hasfocus binding加入View中(請注意,hasfocus的focus首字是小寫)。
<label> <input type="checkbox" data-bind="checked: hasOther" />Others:</label> <input type="text" data-bind="enable: hasOther, hasfocus: hasOther" />執行結果如http://jsfiddle.net/petekcchen/z4YJe/2/,勾選checkbox,嗯!不錯,textobx取得了focus。取消勾選checkbox,咦?取消不了了!
事實上是我誤會hasfocus的意思,hasfocus binding是雙向的(two-way binding),也就是說當勾選checkbox第一次時,因為checkbox將hasOther設為true了,KnockoutJS也就將focus給textbox。但第二次要取消勾選checkbox時,因為離開了textbox(失去focus),所以KnockoutJS就將hasOther馬上設為false,接著checkbox也被KnockoutJS取消勾選。但消取掉後因為此時滑鼠點擊下去了,所以又將checkbox勾選起來,自然textbox又取得focus了。
那要怎麼解決呢?相當簡單,以hasOther()來讀取ViewModel中的hasOther屬性,hasOther在focus變動時就不會寫回ViewModel了,執行結果可參考http://jsfiddle.net/petekcchen/z4YJe/3/,這種作法有點像是讓hasfocus只能唯讀取得hasOther,事實上KnockoutJS的Documentation也有提到讀取ViewModel屬性的方式(Not all browsers support JavaScript getters and setters (* cough * IE * cough *), so for compatibility,
ko.observable
objects are actually functions.)。另一種可能的做法則是透過subscribe函式訂閱hasOther屬性的變動,在函式內判斷當新的值為true時,設定textbox取得focus。
No comments:
Post a Comment