3

親オブジェクトの「サブスクライブ」を取得して、下位レベルのオブザーバブルを変更して起動する簡単な方法はありますか?

次のコードとサンプル フィドルは機能していますが、optionSet で masterOptions を複製する必要があります。この小さいバージョンは扱いやすいですが、masterOptions セットが非常に大きくなる可能性があり、masterOptions と optionSet の両方の保守が困難になり、エラーが発生しやすくなります。

サンプル jsfiddle はここにあります: fiddle

html:

<div>
    Setting1a: <input data-bind="value: masterOptions.group1.setting1a" /><br />
    Setting1b: <input data-bind="value: masterOptions.group1.setting1b" /><br />
    Setting2a: <input data-bind="value: masterOptions.group2.setting2a" /><br />
    Setting2b: <input data-bind="value: masterOptions.group2.setting2b" /><br />
    <br />
    span1: <span data-bind="text: ko.toJSON(optionSet)"></span><br/>
    <br />
    span2: <span id="mySpan"></span>
</div>

脚本:

var masterOptions = {
    group1: {
        setting1a: ko.observable("value1a"),
        setting1b: ko.observable("value1b")
    },
    group2: {
        setting2a: ko.observable("value2a"),
        setting2b: ko.observable("value2b")
    }
};
var optionSet = ko.computed(function () {
    return {
        group1: {
            setting1a: masterOptions.group1.setting1a(),
            setting1b: masterOptions.group1.setting1b()
        },
        group2: {
            setting2a: masterOptions.group2.setting2a(),
            setting2b: masterOptions.group2.setting2b()
        }
    };
});
optionSet.subscribe(function () {
    //alert("Make some magic happen.");
    $("#mySpan").html($("#mySpan").html() + "more magic. ");
});
var ViewModel = function () {
    return {
        masterOptions: masterOptions,
        optionSet: optionSet
    };
};

ko.applyBindings(new ViewModel());

masterOptions を optionSet として再作成する必要はありませんが、下位レベルのオブザーバブルが変更されたときに単一のサブスクライブを起動する方法がわかりません。

4

2 に答える 2

2

計算内の masterOptions で ko.toJS を呼び出すと、うまくいきます。

var optionSet = ko.computed(function () {
    return ko.toJS(masterOptions);
});

[jsfiddle]

これにより、構造内のすべてのオブザーバブルに依存関係が作成されます。また、それに追加されたオブザーバブルは依存関係として含まれます。

ただし、masterOptions に直接サブスクライブしたい場合や、より柔軟性が必要な場合は、ほぼ同じ目的で私が自分で作成したこの便利な小さなプラグインの使用を検討してください。

https://github.com/ZiadJ/knockoutjs-reactor

于 2014-05-27T15:33:19.643 に答える
0

ko mapping pluginの使用を試すことができます。私の解決策が最善かどうかはわかりませんが、それを見ることができます:

HTML

<div>
    Setting1a: <input data-bind="value: masterOptions().group1.setting1a" /><br />
    Setting1b: <input data-bind="value: masterOptions().group1.setting1b" /><br />
    Setting2a: <input data-bind="value: masterOptions().group2.setting2a" /><br />
    Setting2b: <input data-bind="value: masterOptions().group2.setting2b" /><br />
    <br />
    span: <span data-bind="text: json"></span><br/>
    <br />
    span2: <span data-bind="text: magicString"></span>
</div>

JS

var anyData = {
    group1: {
        setting1a: ko.observable("value1a"),
        setting1b: ko.observable("value1b")
    },
    group2: {
        setting2a: ko.observable("value2a"),
        setting2b: ko.observable("value2b")
    }
};

var ViewModel = function (data) {
    var magicString = ko.observable("");

    var masterOptions = ko.computed(function() {
        return ko.mapping.fromJS(data);
    });
    masterOptions.subscribe(function () {
        magicString(magicString() + "more magic. ");
    });

    var json = ko.computed(function() {
        return ko.mapping.toJSON(masterOptions);
    });

    return {
        masterOptions: masterOptions,
        magicString: magicString,
        json: json
    };
};

ko.applyBindings(new ViewModel(anyData));

jsfiddle

于 2014-05-24T06:55:15.483 に答える