重複した値を持つKnockoutJSオプションバインディング

私は、概念の証明としてKnockout.jsを使って簡単なアプリケーションを構築しています。私はKnockoutをとても慣れていないので、この質問のコードは完璧ではないかもしれないし、悪い習慣を示すかもしれないので、もしそうなら、私に知らせてください!

私は options バインディングを使用して select 要素:


ビューモデルは次のようになります。

var ViewModel = function() {
    this.titles = ko.observableArray([]);
};

DOM準備ができたら、私はその観測可能な配列にいくつかの値をプッシュします(各値は "Mr"、 "Mrs"などの "タイトル"を表すオブジェクトリテラルです)。

var data = [
    { value: "Mr", display: "Default Value" },
    { value: "Miss", display: "Miss" },
    { value: "Mr", display: "Mr" },
    { value: "Ms", display: "Ms" }
];
ko.applyBindings(view);
for(var i = 0; i < data.length; i++) {
    view.titles.push(data[i]); //Push titles into observable array
}

なぜ "Mr"という値を持つ2つのオブジェクトがあるのか​​尋ねないでください。これは、対処しなければならないデータのやり方です。私はそれを変更することはできません。しかし、これが問題の原因です。私は最初のオブジェクトが選択されたオプションを表すと期待しますが、そうではありません。 3番目のオブジェクトは、実際にデフォルト選択として終わる option 要素を表します。

これは、観測可能な配列によって、ループが反復するときに option 要素が1つずつDOMに追加されるためです。ノックアウトは、選択したオプションをその値をチェックして保持しようとします。最初の反復の後、選択された option の値は "Mr"です。 3回目の繰り返しの後にKnockoutはそれが以前に選択されたオプションだと思って選択するように "Mr"という値を持つ別の option があります。

この問題を示すフィドルへのリンクがあります。 「デフォルト値」オプションは選択する必要がありますが、選択する必要はありません。ボタンをクリックして同じ値を持つ別のオプションを再度追加すると、そのオプションが選択されますが、ドキュメントによれば、そのオプションは選択されてはなりません。

私の質問は、どのようにこの行動を防ぐことができますですか?

2

1 答え

なぜアイテムを1つずつ配列にプッシュしていますか?あなたはちょうど行うことができます:

view.titles(data);

の代わりに

for(var i = 0; i < data.length; i++) {
    view.titles.push(data[i]); //Push titles into observable array
}

This would also fix your problem - the first item would be selected by default. Also, if you are not planning on adding new items to that array, you could use ko.observable の代わりに ko.observableArray

更新: Knockoutjsは同じ値を持つ複数のオプションが好きではないようです。 selectタグに値バインディングを追加すると、コードが正しく機能しません(最初のアイテムではなく、3番目のアイテムが選択されます)。ただし、knockoutjsを使用すると、(値バインディングを使用して)選択したオブジェクトにアクセスできるので、optionsValueバインディングと値バインディングを使用してvalueバインディングを削除できます。jsfiddle.net/ej9Ue/1

3
追加された
ああ、それは最初にそれを修正します。しかし、新しいオプションを追加してもそれは役に立ちません。この更新されたフィドルを見てください: jsfiddle.net/YuQsz/2 "追加"をクリックすると、 "デフォルト値"は選択されたままであるが、そうではない。
追加された 著者 James Allardice,
@RomanBataev - 私は、非常に良い参照してください。ご協力ありがとうございました。私はKnockoutのソースを見ていて、重複したオプションの値を扱うのではなく、それを扱うことが可能かどうかを見ています。
追加された 著者 James Allardice,
あなたは正しい、knockoutjsは同じ値を持つ複数のオプションが好きではないようです。 selectタグに値バインディングを追加すると、コードが正しく機能しません(最初のアイテムではなく、3番目のアイテムが選択されます)。しかし、knockoutjsでは(値バインディングを使用して)選択したオブジェクトにアクセスできるので、値バインディングを介してoptionsValueバインディングとアクセス値を削除できます。 jsfiddle.net/ej9Ue/1
追加された 著者 Roman Bataev,
これは間違いなく最初のデータの問題を解決しますが、元の質問は、Knockout.jsが以前に選択したオプションを選択する方法でのクワーク/欠陥を強調表示します。要素の値に対してのみチェックし、複数のオプションが同じ値(有効なユースケース)である場合、間違ったものを選択する可能性があります。潜在的な解決策は、一致するかどうかを判断する前に、値と照合してテキストを表示することです。これは、同じ値で新しい表示オプションを追加することで強調表示されますが、表示テキストは異なります。
追加された 著者 antak,
JavaScript - 日本のコミュニティ
JavaScript - 日本のコミュニティ
2 参加者の

日本人コミュニティのjavascript