【问题标题】:Binding Knockout subviewmodel to multiple views?将 Knockout 子视图模型绑定到多个视图?
【发布时间】:2012-08-04 09:16:16
【问题描述】:

我陷入了淘汰赛 JS 绑定问题。我有一个主视图模型,它绑定到我的单页应用程序的外壳页面。此 masterviewmodel 控制当前可见的视图(使用 Sammy JS)。它还保存对绑定到视图的子视图模型的引用。

var app = function () {
    var self = this;

    self.State = ko.observable('home');

    self.Home = ko.observable(new homepageVm());
    self.User = ko.observable(new userInfoVm());
    self.Request = ko.observable(new requestVm());
};

用户视图模型有一个可以像这样绑定的视图:

<div data-bind="with: User, visible: State() === 'user'">
    .. snip ..
</div>

with: 绑定确保正确的子视图模型绑定到视图。 这种方法适用于主视图和用户信息视图。

requestVm 使用向导风格的 UI,需要绑定到多个视图。这是我目前卡住的地方。

<div data-bind="with: Request, visible: State() === 'request-step-1'">
    .. snip ..
</div>

<div data-bind="with: Request, visible: State() === 'request-step-2'">
    .. snip ..
</div>

<div data-bind="with: Request, visible: State() === 'request-step-3'">
    .. snip ..
</div>

当我启动站点时,绑定似乎工作正常(Knockout 没有引发任何绑定错误)但是当我开始通过 VM 推送数据时,它们不再更新 UI,好像所有绑定都被破坏了(即使是那些绑定了一个视图,例如用户虚拟机)。

如果我只包含向导第一步的视图,这使我在请求 VM 上只有一个绑定而不是三个,那么应用程序中的所有绑定都会重新开始工作!

我不知道是什么原因造成的。淘汰赛只能将一个可观察对象绑定到一个元素吗?还是我在尝试一些不受支持的东西?

更新: 我的虚拟机中的 observableArrays 似乎发生了一些事情。与简单可观察对象的绑定工作正常。

这是其中一个虚拟机:

    function userInfoVm() {
    var self = this;

    self.UserName = ko.observable();

    self.Beun = ko.observable();

    self.LoadingUser = ko.observable(false);
    self.LoadingObjects = ko.observable(false);

    self.UserData = ko.observableArray([]);
    self.UserObjects = ko.observableArray([]);

    self.LoadUser = function (userName) {

        self.LoadingUser(true);

        $.get('UserData/UserDetail', { username: userName }, function (details) {
            self.UserData(details);
            self.Beun(JSON.stringify(details));

            self.LoadingUser(false);
        });
    };

    self.LoadObjects = function (userName) {

        self.LoadingObjects(true);

        $.get('UserData/UserObjects', { username: userName }, function (objects) {
            alert(JSON.stringify(objects));
            self.UserObjects([objects]);
            self.LoadingObjects(false);
        });
    };

    self.Load = function (userName) {
        self.UserName(userName);

        self.UserData(null);
        self.UserObjects(null);

        self.LoadUser(userName);
        self.LoadObjects(userName);
    };
};

以及正在使用来自所述 VM 的数据的视图:

<div data-bind="with: User, visible: State() === 'user'">
    <h1>
        <button class="backbutton" onclick="history.back();">
        </button>
        Details for user <span data-bind="text: UserName"></span>
    </h1>
    <div class="display detail">
        <table>
            <tbody data-bind="foreach: UserData">
                <tr>
                    <td class="property" data-bind="text: Key">
                    </td>
                    <td class="value" data-bind="text: Value">
                    </td>
                </tr>
            </tbody>
        </table>
        <div class="loader" data-bind="visible: LoadingUser">
            Please wait while we process your request...
        </div>
    </div>
    <div class="display detail">
        <h1>
            Objects and services for user <span data-bind="text: UserName"></span>
        </h1>
        <table class="detailtable">
            <tbody data-bind="foreach: UserObjects">
                <tr>
                    <td class="value">
                        <a class="service" data-bind="text: Value, attr: { href: '#/service/' + Key }" href="#">
                        </a>
                    </td>
                </tr>
            </tbody>
        </table>
        <div class="loader" data-bind="visible: LoadingObjects">
            Please wait while we process your request...
        </div>
    </div>
    Details for user <span data-bind="text: Beun"></span>
</div>

数组不会向 UI 通知提供给它们的数据。 其他 observables,包括包含来自 AJAX 调用的字符串化数据的 .Beun 会按预期进行更新。

【问题讨论】:

    标签: knockout.js single-page-application


    【解决方案1】:

    您从服务器收到的内容是什么?

    如果您想手动操作,您可以尝试使用 eval(objects) 将数据(字符串)转换为对象,然后使用 foreach 循环中的映射插件 (knockout.mapping.js) 将其转换为可观察数组.

    var data = '[{ "Id": 1, "Titel": "Title1", "Description": "Description 1" }, { "Id": 2, "Titel": "Title 2", "Description": "Description 2" }, { "Id": 3, "Titel": "Title 3", "Description": "Description 3"}]';
    //fist convert your string to JS-objects using eval() ; then to observableArray using mapping pluging
    self.UserObjects = ko.mapping.fromJS(eval(data));
    

    【讨论】:

    • 数据以 JSON 格式来自服务器。我尝试了一些事情,包括手动处理来自服务器的项目。遗憾的是,由于时间限制,我不得不放弃整个嵌套视图模型系统。不过,我并没有完全放弃,在一个(小得多的)概念证明中,它确实按预期工作。
    猜你喜欢
    • 2013-01-03
    • 1970-01-01
    • 2014-03-06
    • 2014-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    相关资源
    最近更新 更多