Select コントロール (Combobox) にアクセスできるシナリオがあり、ソース/オプション リストが変更されたときにイベントを発生させる方法が必要です。
たとえば、最初にオプションとして Option1 と Option2 を持つ選択コントロールがある場合、オプションが Option1、Option3、Option4 に変更されたときにイベントを発生させる方法が必要です。新しいオプションが追加されたのか、削除されたのか、すべての項目が新しく追加されたのかは気にしません。私が欲しいのは、選択コントロールのオプションが変更されたときのイベント ハンドラーだけです。
友人の 1 人は、Option 要素が DOM に追加されると DOM が変更されることを提案しましたが、ページ内の任意の dom 要素が変更されるたびに、変更された DOM が起動されるため、確信が持てません。
更新: 混乱して申し訳ありません。私は選択の変更を探していません。オプションの実際のリストの変更を探しています。
私は Knockoutjs を使用しており、監視可能な配列を選択コントロールにオプションとしてバインドしています。knockoutjs の applybindings は数ミリ秒かかり、その後、監視可能な配列を Select コントロールのオプションとして設定します。新しいオプション セットに基づいて何かを実行できるように、その変更イベントへのフックが必要です。
監視可能な配列の変更を処理しない理由を誰かが言う前に、私はイベント ハンドラーがある場所でその監視可能な配列にアクセスできません。
更新 2:
ここに詳細があります。
このようなカスタムバインディングを持つ選択コントロールがあります。
@Html.KnockOutDropDownListFor(rule => ruleTemplate.RuleReserveWordId, new List<SelectListItem>(), null,
new {data_bind = "options: $root.RuleReserveWords, optionsText:'Name', optionsValue:'RuleReserveWordId', typeaheadCombobox: {sizeClass : 'input-mini'}" }
@Html.KnockoutDropDownlIstFor は、適切なノックアウト関連の属性をすべて備えた選択コントロールを作成するために作成したカスタム ASP.NET MVC ヘルパーです。最終的に、選択コントロールを DOM にレンダリングします。
私が望む選択コントロールは、オートコンプリート/先行入力コモボックスであるはずです。ブートストラップを使用しているため、ここからブートストラップ プラグインを使用しました。
https://github.com/danielfarrell/bootstrap-combobox
カスタム バインディングで、プラグインを呼び出そうとしました。
selectControl.customcombobox();
プラグインは基本的に、選択コントロールの上に入力コントロールを作成し、選択コントロールを非表示にします。同時に、選択コントロールのオプションにアクセスしようとし、ユーザーが入力を開始すると、入力コントロールのドロップダウン メニューとして設定します。
問題は、私が ko.applybindings を非常に早い段階で呼び出すためです (applybindings をどこで呼び出しても、バインディングがすべて設定されると、UI が自動的に更新されるため)、プラグインが呼び出されるまでに、バインディングはまだ行われていません。バウンド。そのため、選択コントロールには実際のオプションが設定されていません。したがって、入力コントロールには値が設定されていません。
数ミリ秒後にプラグインを呼び出すと、それまでにバインドが完了しているため機能します。ただし、サーバーの呼び出しに時間がかかると、再び問題が発生する可能性があるため、危険です。
そのため、どちらかを見つける方法があるかどうかを調べていました
1) jquery を使用して選択コントロールのオプションが更新されたとき (バインド後のオプションなしからいくつかのオプションまで)。これを直接行う方法はありません。一部の人々は更新された DOM を使用することを提案しましたが、すべてのブラウザーで機能するとは限らず、非推奨です。
また
2) ノックアウトで、選択コントロールにバインドされた実際の observablearray がいつ更新されるかを調べる方法を見つけます (この例では RuleReserveWords)。これは私の好みの方法です。
選択コントロールで選択された値が変更されるたびに呼び出されるため、「更新」を使用できません。これは私が望むものではありません。
オプションをいつ更新するかを知っている限り、オプションを更新する方法があります。
私が試した別の方法はこれでした。プラグインを呼び出す前に、自分でコントロールを選択するオプションを追加しようとしました。DOM は正常にレンダリングされますが、どういうわけか、バインディングの直後に選択が設定されません。
ko.bindingHandlers.typeaheadCombobox = {
init: function (element, valueAccessor, allBindingsAccessor)
{
var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
var selectControl = $(element);
var options = allBindingsAccessor().options;
var optionsValuePropertyName = allBindingsAccessor().optionsValue;
var optionsTextPropertyName = allBindingsAccessor().optionsText;
//Add appropriate class for the typeahead combobox plugin to work
selectControl.addClass('combobox');
$.each(options(), function (index, option)
{
var value = null;
var text = null;
for (var propertyName in option)
{
if (propertyName)
{
if (propertyName == optionsValuePropertyName)
{
value = option[propertyName];
}
else if (propertyName == optionsTextPropertyName)
{
text = option[propertyName];
}
}
}
if (value && text)
{
selectControl.append('<option value=' + value() + '>' + text() + '</option>');
}
});
//Call bootstrap custom combobox plugin on the select control
selectControl.customcombobox(options());
//Find the input control that is created by the bootstrap custom combobox plugin to set input control settings like size, style, validation attributes, etc
var inputControl = selectControl.parent().find('input');
inputControl.attr('name', selectControl.attr('name'));
inputControl.attr('data-val', selectControl.attr('data-val'));
inputControl.attr('data-val-required', selectControl.attr('data-val-required'));
inputControl.attr('style', selectControl.attr('style'));
if (inputControl && valueUnwrapped && valueUnwrapped.sizeClass) //Used the sizeClass instead of class itself becasue IE7 was having issues if using class or 'class' for custom bindings.
{
inputControl.addClass(valueUnwrapped.sizeClass);
}
}