是否有可能让knockoutjs更新'initialdata'对象?

时间:2012-02-08 19:37:05

标签: javascript data-binding mvvm viewmodel knockout.js

以下是我正在尝试使用knockoutjs进行简化的示例:

<!DOCTYPE HTML>
<html>
    <head>
        <title>test</title>
        <script type="text/javascript" src="https://github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.debug.js"></script>
        <script type="text/javascript">

            var derp = { "foo": 1, "bar": 2 };

            window.onload = function() { go(); }

            function go()
            {
                var ViewModel = function(foobar)
                {
                    this.foo = ko.observable(foobar.foo);
                    this.bar = ko.observable(foobar.bar);
                }

                ko.applyBindings(new ViewModel(derp));
            }

        </script>
    </head>
    <body>
        <input data-bind="value: foo"/>
        <input data-bind="value: bar"/>
        <button onclick="go();">Go</button>
    </body>
</html>

此代码的目标是让knockoutjs更新derp中的值,而不是ViewModel中的副本。

有没有办法通过淘汰赛轻松实现这一目标,还是我在错误的树上咆哮?

编辑上下文:

这是从一个更大的应用程序中挑选出来的。我的意图是使用knockout来显示和编辑一个大的,毛茸茸的javascript对象的属性。这些对象由用户动态实例化,并且可以随意切换。

在我发现找到淘汰赛之前,我手动创建了DOM元素来进行每个对象的显示和编辑,这些对象很麻烦且很麻烦。我在C#中通过WPF有一些MVVM经验,并且更倾向于使用这种方法。我对淘汰赛的初步了解是,它就是这样,没有意识到ViewModel复制了ko.observable *捕获的值。 ViewModel对我来说仍然有用,因为它允许我有条件地公开和简化对我想要编辑的成员的访问。

2 个答案:

答案 0 :(得分:3)

我喜欢使用Save方法的@Etch响应。这有很大帮助。 但是如果你想自动化这样的事情,那么我会在{oborables上使用subscribe

也许这不是一种更干净的方式。如果我能通过引用传递变量会更高兴。

我更喜欢在observables周围使用一些包装器来输入less:

var returnFireObservable = function(variable, property) {
    var obs = ko.observable(variable[property]);
    obs.subscribe(function(newValue) {
        variable[property] = newValue;
    });
    return obs;
};

以这种方式使用代码:

var ViewModel = function(foobar) {
    this.foo = returnFireObservable (foobar, "foo");
    this.bar = returnFireObservable (foobar, "bar");
};

ko.applyBindings(new ViewModel(derp));

小演示http://jsfiddle.net/AlfeG/eQ9Zf/2/

希望这有帮助。

答案 1 :(得分:1)

我不是百分百肯定我完全理解你想要的东西,但我会对它采取一些措施。

您已将模型定义为:

var ViewModel = function(foobar)
            {
                this.foo = ko.observable(foobar.foo);
                this.bar = ko.observable(foobar.bar);
            }

您使用var derp = { "foo": 1, "bar": 2 }; aka lotmorecomplicatedobject初始化了淘汰模型。

因此,您的输入会因data-bind标记而获得这些值。然后,您可以修改这些输入值,然后点击“保存”按钮并想要更新原始的javascript对象。

如果是这样的话,我会倾向于......

将viewModel更改为:

var ViewModel = function(foobar)
                {

                    this.foo = ko.observable(foobar.foo);
                    this.bar = ko.observable(foobar.bar);
                    save: function() { derp.foo = this.foo;
                                       derp.bar = this.bar;          
                        //  ko.utils.postJson(location.href, { obj1: this.foo, obj2: this.bar });
                    }
                }

然后将您的按钮点击事件更改为:ViewModel.save();

我添加了postJson对象作为示例,因为这是我处理该类型数据的方式。我看一下你传递给初始ViewModel定义的变量就是那个..这是我希望从那一点预先填充我的viewmodel的数据我将ViewModel用于所有内容。一旦你采取了这种心态,你就不需要更新原始对象。