【问题标题】:Is it possible to have knockoutjs update the 'initialdata' object?是否可以让 knockoutjs 更新“初始数据”对象?
【发布时间】:2012-03-01 07:03:12
【问题描述】:

这是我尝试用 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 中的副本。

有没有办法通过淘汰赛轻松完成此任务,还是我找错了树?

编辑上下文:

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

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

【问题讨论】:

  • 我只是好奇为什么你会尝试使用 knockoutjs 而不想使用该模型。我的意思是你可以只使用普通的 javascript 来修改原始的 derp ob,但我认为我不完全理解你为什么要尝试解决 ko.js。也许我需要更多关于您要完成的工作的背景信息。
  • 当然,我将编辑问题以添加一些上下文。

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


【解决方案1】:

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

也许这不是一种更清洁的方法。如果我能够通过引用传递变量会更高兴。

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

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/

希望这会有所帮助。

【讨论】:

  • 确实有帮助。这看起来是一个很好的折衷方案,因为看起来我正在尝试让淘汰赛做一些它不是为之设计的事情。
【解决方案2】:

我不是 100% 确定我完全理解你想要什么,但我会努力解决的。

您已将模型定义为:

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

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

因此,由于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 并且永不回头是要走的路,但我真正的“初始数据”是由不同库生成的复杂 javascript 对象。项目的其他部分严重依赖它,所以我不能轻易放弃它。
  • 我不知道,我认为初始数据正是 Knockoutjs 对待它的方式,以及他们网站上的术语为何如此。如果 javascript 必须保留,只需使用 save 方法将 viewmodel 值保留到您的原始对象。我认为@AlfeG 有另一个不错的选择。
猜你喜欢
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
  • 2022-08-14
  • 2018-09-09
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
相关资源
最近更新 更多