【问题标题】:knockout mapping plugin, create observable for head node also淘汰映射插件,也为头节点创建可观察对象
【发布时间】:2014-03-22 02:02:11
【问题描述】:

有谁知道如何设置映射选项以使头节点成为可观察的?

例如,如果我有这样的结构:

var myModel = {
table: [{...},{...},{...}]
configOptions: { someoptions... }
otherstuff: thisbecomesanobservable
}

我打电话给

var data = ko.mapping.fromJS(myModel)

由于某种原因,data 不是可观察的,只有树叶是。 这意味着当我稍后调用时

ko.mapping.fromJS(ajaxResponse, {}, data);

而且我需要订阅和依赖数据,但我不能,因为它不可观察。

我现在这样做是为了手动包装它:

if (typeof vm.Table === 'undefined') {
    vm.Table = ko.observable();
    vm.Table(ko.mapping.fromJS(response.Model));
}
else {
    var temp = vm.Table();
    ko.mapping.fromJS(response.Model, {}, temp);
    vm.Table(temp); 
}

但是在每次ajax调用之后都必须把所有这些都放在非常痛苦的地方

有什么建议吗?想法?想法?我怎样才能做到这一点?

谢谢!

【问题讨论】:

    标签: knockout.js knockout-mapping-plugin


    【解决方案1】:

    我试图重构你在做什么(我冒昧地将你的 data 变量重命名为 vm,因为这确实是你的视图模型):

    标记:

    <ul data-bind="foreach: table">
        <li data-bind="text: someProperty"></li>
    </ul>
    
    <label>Hax option value:</label>
    <label data-bind="text: configOptions.hax"></label>
    
    <input type="button" data-bind="click: doAjaxCall" value="Get new stuff" />
    

    脚本:

    <script>
        var initialModel = {
            table: [{ someProperty: 1 }, { someProperty: 2 }],
            configOptions: { hax: '2tm' },
        };
    
        $(document).ready(function() {
    
            var vm = ko.mapping.fromJS(initialModel);
    
            //Attach a function to viewmodel before binding
            vm.doAjaxCall = function(dataVal, event)
            {
                //A Json object, we pretend, this came back from an AJAX call.
                //Obviously, it should have same layout as initial object, base for the viewmodel.
                var newData = {
                    table: [{ someProperty: 3 }, { someProperty: 4 }, { someProperty: 5 }],
                    configOptions: { hax: '4tm' },
                };
    
                //Update viewmodel with the new data
                ko.mapping.fromJS(newData, vm);
            };
    
            //Init knockout
            ko.applyBindings(vm);
        });
    </script>
    

    单击该按钮,您应该会看到 vm 得到更新、冒泡并更新数据绑定对象。

    是这样的吗?如果您有类似的代码,但无法正常工作,请提供jsfiddle 或类似代码。


    【讨论】:

    • 不,我需要 vm.data 不更新整个视图模型,只是它的一部分。现在把小提琴放在一起。
    • 请看那个小提琴。我需要 ComplexViewModel1 和 ComplexViewModel2 来保持可观察性。因为我有自定义绑定需要在更新时执行操作等。为简单起见,我没有将所有内容都放在示例中,只是让您了解我正在尝试做什么
    • 这真的很难理解,你在做什么。你写“我需要 vm.data 不更新整个视图模型” - 什么 vm.data?您的虚拟机上没有“数据”属性。 “我需要 ComplexViewModel1 和 ComplexViewModel2 来保持可观察性”——他们会的。你是什​​么意思?我会尽我所能帮助你,但请拿出一个可行的例子——你可以在浏览器中实际运行的东西,然后发生一些事情——并解释问题是什么。跨度>
    • 感谢您的帮助,我想通了。
    • 感谢您的帮助,它使我走上了正确的道路,对不起,我不太清楚,我试图使用映射选项来导致我在上面所做的事情,很难解释.我想做的就是使用 mapping.fromJS 从服务器获取数据并将其放入 observable 中。但不是像所有示例所示的整个视图模型。
    【解决方案2】:

    如果这对某人有帮助,当您从服务器获取数据及其复杂对象时,这就是如何将其包装在可观察对象中:

    vm.updateModel = function (observable, data) {
        if (observable() == undefined)
            observable(ko.mapping.fromJS(data));
        else {
            var temp = observable();
            ko.mapping.fromJS(data, {}, temp);
            observable(temp);
        }
    };
    

    令人震惊的是,映射插件在默认情况下或使用 mappingOptions 都无法做到这一点......

    【讨论】:

      猜你喜欢
      • 2018-10-13
      • 2012-08-07
      • 2017-08-11
      • 2023-04-06
      • 2012-10-14
      • 1970-01-01
      • 2013-05-30
      • 2017-06-02
      • 2012-07-07
      相关资源
      最近更新 更多