2

私は Durandal と Knockout を初めて使用し、問題に遭遇しました。解決方法がわかりません。

私は、クレジットカードラインの表を含むビューを持っています。各行には、Dimension1Key と Dimension2Key という名前の 2 つのネストされたドロップダウンがあり、GetDimensionMatrix ajax 呼び出しから入力されます。

foreach のクレジットラインは、2 つのドロップダウンが監視可能として定義されている for ループに取り込まれ、Dimension2 のデータは ko.compute として計算されます。

テーブルとドロップダウンは、最初は正しい値が選択されて正しく設定されていますが、ネストが正しく機能していません。どの Dimension1 ドロップダウンを変更しても、selfの参照はテーブルの最後の行に対するものです。したがって、対応する Dimension1 の Dimension2 に、最後の行の選択した値の値が入力されます。Dimension1 の値が再度変更されても、何も起こりません。計算された関数への参照が壊れています。しかし、最後の行の Dimension1 の値を変更すると、以前に変更された行 Dimension2 の値が変更されます。まるで、その参照が最後の行に接続されているかのようです。

問題は、ビューモデルのループ内の自己とそれが存在するコンテキストであると確信していますが、解決策に頭を悩ませることはできません。

何か助けはありますか?:-)

意見:

<section>
    <h2 data-bind="html:displayName"></h2>

    <table class="table">
        <tbody data-bind="foreach: creditCardLines">
            <tr>
                <td class="date" data-bind="text: Date"></td>
                <td class="date" data-bind="text: DocumentNo"></td>
                <td data-bind="text: Description"></td>
                <td><select data-bind="options: $parent.dimension1List, optionsText: 'DimensionValue', optionsValue: 'DimensionKey', value: Dimension1Key"></select></td>
                <td><select data-bind="options: dimension2List, optionsText: 'DimensionValue', optionsValue: 'DimensionKey', value: Dimension2Key"></select> </td>
                <td data-bind="text: Currency"></td>
                <td data-bind="text: CurrencyAmount"></td>
                <td data-bind="text: ExchangeRate"></td>
                <td data-bind="text: AmountLCY"></td>
                <td data-bind="text: Comment"></td>
                <td data-bind="text: ApprovedEmployee"></td>
                <td data-bind="text: Id"></td>
            </tr>
        </tbody>
    </table>
</section>

ビューモデル:

define(function (require) {

var submit = function () {
    this.displayName = 'Rejseafregning';

    this.creditCardLines = ko.observableArray();

    var me = this;

    this.activate = function () {
        return $.when(
                $.get('/submit/GetCreditCardLines'),
                $.get('/submit/GetDimensionMatrix')
                )
            .then(function (creditCardLines, dimension1List) {
                me.dimension1List = dimension1List[0].Data;

                for (var i = 0; i < creditCardLines[0].Data.length; i++) {
                    var self = creditCardLines[0].Data[i];

                    self.Dimension1Key = ko.observable(creditCardLines[0].Data[i].Dimension1Key);
                    self.Dimension2Key = ko.observable(creditCardLines[0].Data[i].Dimension2Key);


                    self.dimension2List = ko.computed(function () {
                        for (var j = 0; j < me.dimension1List.length; j++) {
                            if (me.dimension1List[j].DimensionKey === self.Dimension1Key()) {
                                return me.dimension1List[j].DimensionNext;
                            }
                        }
                    });

                    me.creditCardLines.push(self);
                }
            });
        };
    };
    return submit;
});
4

1 に答える 1

2

を作成するときに、計算された が評価されるときのko.computed値を制御する 2 番目の引数を渡すことができます。this

計算済みを作成するときは、現在の値を 2 番目の引数としてdimension2List渡し、次のようにメソッドで使用します。selfthis

            self.dimension2List = ko.computed(function () {
                for (var j = 0; j < me.dimension1List.length; j++) {
                    if (me.dimension1List[j].DimensionKey === this.Dimension1Key()) {
                        return me.dimension1List[j].DimensionNext;
                    }
                }
            }, self);

それ以外のself場合、計算が再評価されるときの値はself、JS でクロージャーが機能する方法に基づいて、最後に設定された値 (最後の行) になります。

の 2 番目の引数を使用computedすると、その特定の値がコンテキストとして使用されるようになります。

于 2013-04-15T14:42:06.950 に答える