【问题标题】:knockoutjs child object trigger change in parent computedknockoutjs 子对象触发更改父计算
【发布时间】:2014-07-05 12:24:20
【问题描述】:

有没有一种更简单的方法可以让父对象的“订阅”随着对任何较低级别的可观察对象的更改而触发?

以下代码和示例小提琴正在工作,但它需要我在 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,但我不明白当任何较低级别的 observables 发生变化时,我如何才能触发一次订阅。

【问题讨论】:

  • 当它只返回masterOptions 中的任何内容时,拥有optionSet 有什么意义?
  • 您不必将它们复制为“详细”...您可以这样做programmatically。但如前所述,您要达到的目标还不是很清楚。描述一下,它可能有助于通过替代方法回答您的问题。
  • 拥有 optionSet 对象的唯一一点是,我可以让 obptionSet.subscribe 函数在任何较低级别的 observables 发生变化时触发。在不创建 optionSet 对象的情况下,我还没有想出在 subscribe 中调用函数的方法。

标签: knockout.js parent subscribe computed-observable


【解决方案1】:

在你计算的 masterOptions 上调用 ko.toJS 就可以了:

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

[ jsfiddle ]

这会在结构中创建对每个可观察对象的依赖关系。此外,添加到其中的任何 observables 都将作为依赖项包含在内。

但是,如果您想直接订阅 masterOptions 和/或需要更多灵活性,您可以考虑使用我自己编写的这个方便的小插件,目的几乎相同:

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

【讨论】:

    【解决方案2】:

    您可以尝试使用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

    【讨论】:

      猜你喜欢
      • 2019-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-22
      • 2022-01-11
      相关资源
      最近更新 更多