Вычислено изменение триггера дочернего объекта 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);
});
Это создает зависимость от каждого наблюдаемого в структуре. Также любые наблюдаемые, добавленные к нему, будут включены как зависимости.
Однако, если вы хотите подписаться непосредственно на masterOptions и / или вам нужна большая гибкость, вы можете рассмотреть возможность использования этого удобного небольшого плагина, который я написал сам для почти тех же целей:
Вы можете попробовать использовать плагин 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));