2012-09-06 8 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> 

のViewModel:

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

私は上記のカスタムバインディングジョンアールを使用しようと一緒にもvalueUpdateを使用テキストフィールドで(おかげジョン!):「afterkeydown」結合とことが判明それは実際には期待どおりに動作しませんでした。 (これは、バインディングの1つが起動する必要があるときにすべてのバインディングが再度呼び出され、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デバイスで使用した場合とまったく同じように動作しない可能性があります。バインディングには何も問題はありませんが、オートフォーカスとセレクトロジックによって、バインディングが実行されるとすぐにデバイスのキーボードが起動します。これは、まさにそのようなデバイスで起こりたいことかもしれません。比較するために、テストするために使用するアンドロイドデバイスでは、このバインディングが実行されるとすぐに自動的にキーボードを取得しません。私のために、私は、次のように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); 
     } 
    } 
}; 

Tlの; DR:

あなたがこれを使用すると、タブレット/スマートフォンに応えるためにしたい場合は、これはあなたが実際に期待するインタラクションロジックであることをテストしてください。

関連する問題