使用mvc3 knockout.js和sammy.js的单页面应用程序

时间:2012-08-06 15:07:07

标签: asp.net-mvc asp.net-mvc-3 knockout.js sammy.js

我被困在项目的一个特定部分,其中包含标题中提到的组件。

我目前有一个概念证明,它的工作方式与我希望的方式相同:

  • Sammy被整合到淘汰视图模型中(根据教程 在淘汰赛网站上)
  • 视图由控制器按需加载 (所以我不必在应用程序页面上定义每个视图)

在我目前的情况下,我在应用程序启动时实例化viewmodels(如果我不实例化它们,Sammy将不会处理路由)。问题是Sammy加载和交换视图的位置。我必须调用ko.applyBindings来让KO绑定到视图。但反复呼吁申请的不良做法。

我的问题是,如何绑定我按需加载的视图?我无法调用ko.applybindings,因为当视图加载多次时会产生内存泄漏。

以下是一个示例VM,其中包含违规的ko.applyBindings:

function serviceInfoVm() {
var self = this;

self.ObjectKey = ko.observable();
self.Service = ko.observable();

self.LoadService = function () {
    $.get('ServiceData/Detail', { serviceId: self.ObjectKey() }, function (data) {
        self.Service(data);
    });
};

$.sammy('#content', function () {
    this.get('#/service/:id', function (context) {
        var ctx = context;
        self.ObjectKey(this.params['id']);

        self.LoadService();

        $.get('Content/ServiceInfo', function (view) {
            ctx.app.swap(view);
            ko.applyBindings(self);
        });
    });

}).run();
};

任何有这个问题的指针和/或解决方案的人?

3 个答案:

答案 0 :(得分:3)

您在viewmodel中拥有Sammy代码,如果该视图模型将存在且您希望加载子视图模型和视图,则该代码可以正常工作。所以我认为这就是你要做的。深思熟虑......将sammy代码分离到自己的模块中(我称之为router.js中的路由器)并让它将导航与任何视图模型分开管理。

但回到你的代码......你可以设置子视图和子视图模型,并在调用sammy.get之前对它们使用applybindings。基本上,您提前注册路线。然后sammy.get只导航到新视图,该视图已经是数据绑定。

答案 1 :(得分:1)

不是解决方案,而是另一种方法:

放弃了动态加载视图的想法。 现在,我的视图始终显示在页面中,并且可见性由此代码触发:

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

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

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

$.sammy(function () {

    this.get('#/', function (context) {
        self.State('home');
    });

    this.get('#/info/:username', function (context) {
        self.State('user');
        self.User().UserName(context.params['username']);
        self.User().LoadInfo();
    });

}).run();

};

以这种方式触发div可见性:

<div id="homeView" data-bind="with: Home, visible: State() === 'home'">

这样,只需在应用启动时调用一次ko.applyBindings。 上面的viewmodel绑定到我们的shell页面。

有关此here

的更多信息

答案 2 :(得分:0)

在返回的模板中的特定元素上调用applyBindings是一个选项:

ko.applyBindings(viewModel, htmlNode) 

另请参阅有关延迟加载模板的此问题:knockout.js - lazy loading of templates

这里有关于applyBindings的文档:http://knockoutjs.com/documentation/observables.html

相关问题