2

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

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

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

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

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

我的想法是使用 PagerJS 在不同的视图之间轻松切换,但它需要在 SammyJS 中设置的路径和用于 PagerJS 的数据绑定路径之间进行同步。例如,选择#!/用户时,Sammy中的路由会处理请求并获取要显示的数据,并显示Pagerjs显示用户页面。对我来说感觉有点脆弱,但这也许是它应该如何工作的。

4

1 回答 1

2

Some caveats beforehand:

I'm using RequireJS to divide my app up into modules - this isn't necessarily required (no pun intended) - you could just dump everything in one Javascript file and have it work, I just find it easier to organize and work with. This question shows how my project is laid out.

I'm also not using SammyJS for routing, but Crossroads and Hasher. The concepts should be somewhat the same though.

The examples below probably aren't a 100% match for what you're doing, but hopefully it gives you an idea of the approach I'm using.

My main.js contains all the routing info, and inside each route handler, I use require() from RequireJS to pull in the module(s) I'm using for that route. Each module contains the Knockout ViewModel and several methods to do things like load data for the ViewModel, bind it in certain contexts, etc.

main.js here's how I handle the route to show the #/person/id route:

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

Significant parts of 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;
});
于 2013-02-22T14:11:28.707 回答