Вычислено изменение триггера дочернего объекта knockoutjs в родительском объекте

Есть ли более простой способ заставить подписку родительского объекта сработать с изменениями любого из наблюдаемых нижнего уровня?

Следующий код и пример скрипта работают, но он требует, чтобы я продублировал свои masterOptions в optionSet. Эта меньшая версия является управляемой, но мой набор 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, но я не вижу, как я могу иметь один огонь подписки при изменении любого из наблюдаемых нижнего уровня.

2 ответа

Решение

Вызов ko.toJS для masterOptions внутри вашего компьютера сделает свое дело:

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

[jsfiddle]

Это создает зависимость от каждого наблюдаемого в структуре. Также любые наблюдаемые, добавленные к нему, будут включены как зависимости.

Однако, если вы хотите подписаться непосредственно на masterOptions и / или вам нужна большая гибкость, вы можете рассмотреть возможность использования этого удобного небольшого плагина, который я написал сам для почти тех же целей:

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

Вы можете попробовать использовать плагин ko mapping. Я не уверен, что мое решение является лучшим, но вы можете посмотреть на него:

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

Другие вопросы по тегам