2012-09-06 19 views
10

我是Knockout.js的新手。Select()使用Knockout.js輸入字段

什麼是最佳方式爲select()<input />何時變爲可見?

查看:

<p> 
    Name: 
    <b data-bind="visible: !editing(), text: name, click: edit">&nbsp;</b> 
    <input data-bind="visible: editing, value: name, hasfocus: editing" /> 
</p> 

視圖模型:

function PersonViewModel(name) { 
    // Data 
    this.name = ko.observable(name); 
    this.editing = ko.observable(false); 

    // Behaviors 
    this.edit = function() { this.editing(true) } 
} 

ko.applyBindings(new PersonViewModel("Bert Bertington")); 

http://knockoutjs.com/documentation/hasfocus-binding.html

http://jsfiddle.net/RnCUd/

謝謝!

回答

18

您可以創建一個新的綁定來處理選擇。

ko.bindingHandlers.selected = { 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var selected = ko.utils.unwrapObservable(valueAccessor()); 
     if (selected) element.select(); 
    } 
}; 

將此綁定添加到您的輸入字段。

<input data-bind="visible: editing, value: name, hasfocus: editing, selected: editing" /> 

這裏是一個小提琴:http://jsfiddle.net/RnCUd/2/


或者,你可以創建一個自定義綁定包裝了hasfocus結合:

ko.bindingHandlers.hasSelectedFocus = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     ko.bindingHandlers['hasfocus'].init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
    },   
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     ko.bindingHandlers['hasfocus'].update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);   

     var selected = ko.utils.unwrapObservable(valueAccessor()); 
     if (selected) element.select(); 
    } 
}; 

這只是結合代表初始化和更新hasfocus並在可觀察性爲真時負責選擇元素。用它代替hasfocus

<input data-bind="visible: editing, value: name, hasSelectedFocus: editing" /> 

這裏是一個小提琴:http://jsfiddle.net/RnCUd/1/

+0

感謝您的快速回答:)使用自定義綁定*太多*在這一點上?也許這是**最好的**,但我認爲自定義綁定是提前的......有沒有使用自定義綁定的「足夠好」的簡單方法?或者是自定義綁定沒有什麼大不了的,我應該學習如何及早和經常使用它們? (注意:我從來沒有做過自定義jQuery選擇器):) –

+2

@QuangVan我會催促你去了解自定義綁定。當問題跨越數據和DOM之間的界限並且無法通過標準綁定解決時,自定義綁定是正確的選擇。如你所說,我想說你應該隨時「早點使用它們」。它們是一個強大的工具,不一定是最後的手段。 –

+0

好吧,我認爲這是「最後的手段」...謝謝你:) –

1

我試圖用約翰Earles以上的自定義綁定(感謝約翰!)有一個文本字段,也採用了valueUpdate起來:「afterkeydown」結合,結果發現,這並沒有像預期的那樣真正起作用。 (我猜這是因爲當其中一個綁定需要觸發時,所有綁定都會再次觸發,並且在每個字符被寫入後,valueUpdate最有可能導致綁定值被觸發)。

經過幾次嘗試之後,我爲這個問題做了一個半解決方案,似乎對我來說工作正常。基本的想法是,在我們觸發hasfocus綁定之前,我們檢查所討論的元素是否已經有焦點,並且在hasfocus綁定已經觸發之前,實際上只有當元素沒有焦點時才選擇文本。

我已經使用jquery來檢查焦點,但你也可以用其他方式來做。

ko.bindingHandlers.hasSelectedFocus = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     ko.bindingHandlers['hasfocus'].init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var focusBefore = $(element).is(':focus'); 
     ko.bindingHandlers['hasfocus'].update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 

     var selected = ko.utils.unwrapObservable(valueAccessor()); 
     if (selected && !focusBefore) { 
      element.select(); 
     } 
    } 
}; 

編輯:我注意到,這種綁定可能無法像在iOS設備上一樣使用。綁定沒有任何問題,但自動對焦和選擇邏輯會在綁定執行後立即啓動設備鍵盤,這可能是也可能不是您想要在此類設備上發生的事情。爲了進行比較,在我用來測試的android設備上,只要綁定執行,我就不會自動獲取鍵盤。爲了我的緣故,我最終創建了另一個綁定,以下面的方式在iOS設備上不做任何事情。

ko.bindingHandlers.hasNonIosSelectedFocus = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     if (navigator.userAgent.match(/iPad/i) == null && navigator.platform.indexOf("iPhone") == -1 && navigator.platform.indexOf("iPod") == -1) { 
      ko.bindingHandlers['hasSelectedFocus'].init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
     } 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     if (navigator.userAgent.match(/iPad/i) == null && navigator.platform.indexOf("iPhone") == -1 && navigator.platform.indexOf("iPod") == -1) { 
      ko.bindingHandlers['hasSelectedFocus'].update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
     } 
    } 
}; 

鉈;博士:

如果你使用這個,想迎合平板電腦/智能手機的話一定要檢驗,這是你真正所期望的交互邏輯。