【问题标题】:How to organize a SPA with KnockoutJS, SammyJS and pagerJS如何使用 KnockoutJS、SammyJS 和 pagerJS 组织 SPA
【发布时间】:2013-02-07 22:46:24
【问题描述】:

我刚刚开始使用 KnockoutJS,我正在将它与 PagerJS、SammyJS 和 BootStrap 结合使用来构建单页应用程序,我现在有点迷茫。

让我吃惊的是我应该如何组织视图模型并以简单且可重用的方式组合路由和页面?现在感觉就像一堆松散的碎片,几乎不适合。我已经检查了一些关于 SO 的答案,但我仍然没有掌握如何组织应用程序。

目前我在页面上有一个视图模型,作为概念证明,它只处理用户个人信息和即将发生的事件的显示。但是,现在我必须合并其他类型的信息,并且拥有一个视图模型,而不是多个视图模型似乎是不对的,因为期望用户能够管理他/她的事件、联系人和任务并列出其他用户、事件和任务等。还有更多。

用户选择/选择的几乎所有选项都在数据库中定义。例如,用户任务和解决这些任务的相应动作是在数据库中预定义的。

大多数示例倾向于将 SammyJS 路由放在 viewmodel 中,但是当页面上有多个 viewmodel 时,我想将 SammyJS 从单个 viewmodel 移动到自己的位置,即在一个地方编辑路由。

我的想法是使用 PagerJS 在不同的视图之间轻松切换,但它需要在 SammyJS 中设置的路径和用于 PagerJS 的数据绑定路径之间进行同步。 For example when selecting #!/user then the routing in Sammy handles the request and fetches the data to be displayed and PagerJS shows the user page.对我来说感觉有点脆弱,但这也许就是它应该的工作方式。

【问题讨论】:

  • 你也可以看看Knockback;一个采用 Knockout 和 Backbone 的“两全其美”的框架(包括路由和历史支持)。

标签: javascript knockout.js single-page-application sammy.js pagerjs


【解决方案1】:

一些注意事项:

我正在使用 RequireJS 将我的应用程序划分为模块 - 这不是必需的(没有双关语) - 你可以将所有内容转储到一个 Javascript 文件中并让它工作,我只是发现它更容易组织和合作。 This question 展示了我的项目是如何布局的。

我也没有使用 SammyJS 进行路由,而是使用 Crossroads 和 Hasher。不过,概念应该有些相同。

以下示例可能与您正在做的事情不是 100% 匹配,但希望它能让您了解我正在使用的方法。

我的main.js 包含所有路由信息,在每个路由处理程序中,我使用 RequireJS 中的require() 来拉入我用于该路由的模块。每个模块都包含 Knockout ViewModel 和几个方法来做一些事情,比如为 ViewModel 加载数据,在特定的上下文中绑定它等等。

main.js 这是我处理路由以显示#/person/id 路由的方式:

crossroads.addRoute("person/{id}", function(id){
    require(["person"], function(person) {
        var model = person.load(id);
        person.view($('#content'), model);
    });
});

person.js 的重要部分:

define(['jquery', 'knockout', ...], function($, ko, ...) {
    var person = {};
    person.Model = function Model(id) {
        this.id = ko.observable(id);
        this.name = ko.observable();
        // more properties and methods removed...
    };

    person.load = function(id) {
        var model = new person.Model(id);
        var request = $.ajax({
            // ajax config properties removed...
            'success' : function(resp) {
                model.name (resp.name);
                // more property setting removed...
            }
        });
        return model;
    };

    person.view = function(element, model) {
        // Using require text plugin to load templates...
        require(['text!templates/person/view.tmpl.html'], function(ViewTemplate) {
            element.empty();
            element.html(ViewTemplate).ready(function() {
                ko.applyBindings(model, element.get(0));
                // any further setup needed below...
            });
        });
    };
    return person;
});

【讨论】:

  • 感谢您的回复。你的方法绝对看起来很有趣。您不使用任何辅助库(如 pagerjs)在视图之间切换 - 我假设您正在为每个视图使用模板?我现在正在考虑摆脱 pagerjs,因为它扰乱了我对应该如何继续进行的看法。
猜你喜欢
  • 1970-01-01
  • 2015-03-21
  • 1970-01-01
  • 2012-11-09
  • 2018-10-19
  • 2020-08-09
  • 1970-01-01
  • 2016-08-19
  • 1970-01-01
相关资源
最近更新 更多