【问题标题】:Single page application using mvc3 knockout.js and sammy.js使用 mvc3 knockout.js 和 sammy.js 的单页应用程序
【发布时间】:2012-08-03 13:56:37
【问题描述】:

我被困在项目的一个特定部分,该部分由标题中提到的组件组成。

我目前有一个按我希望的方式工作的概念证明:

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

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

我的问题是,如何绑定到按需加载的视图?我不能调用 ko.applybindings,因为当视图被多次加载时会造成内存泄漏。

这是一个带有违规 ko.applyBindings 的示例 VM:

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();
};

有人对此问题有一些指示和/或解决方案吗?

【问题讨论】:

  • 您是否有理由要使用 sammy swap 而不是淘汰模板?查看 html 文件插件 github.com/ifandelse/Knockout.js-External-Template-Engine 中的外部模板,它应该可以满足您的要求(如果我理解正确的话)
  • 我想动态加载视图..但现在放弃了这个想法。在下面查看我自己的答案

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    最终放弃了动态加载视图的想法。 现在我的视图总是出现在页面中,可见性是由这段代码触发的:

    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

    【讨论】:

      【解决方案3】:

      对返回模板中的特定元素调用 applyBindings 是一种选择:

      ko.applyBindings(viewModel, htmlNode) 
      

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

      applyBindings 的文档在这里:http://knockoutjs.com/documentation/observables.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-22
        • 1970-01-01
        • 1970-01-01
        • 2012-06-30
        • 1970-01-01
        • 1970-01-01
        • 2016-02-27
        • 2015-08-30
        相关资源
        最近更新 更多