KnockoutJS与Sammy.js SPA建议

时间:2014-05-05 20:48:12

标签: javascript jquery knockout.js knockout-2.0 sammy.js

我正在构建一个具有以下结构的SPA应用程序:

<body>
    <!-- Main Container for our application -->
    <div id="main">

    </div>
    <!-- End Main Container -->

    <!-- Vendor Libraries -->
    <script src="js/vendor/jquery/jquery-1.11.0.min.js"></script>
    <script src="js/vendor/knockout/knockout-3.1.0.js"></script>
    <script src="js/vendor/sammy/sammy-latest.min.js"></script>

    <!-- Models -->
    <script src="js/models/model1.js"></script>

    <!-- ViewModels -->
    <script src="js/viewmodels/viewModel1.js"></script>
    <script src="js/viewmodels/viewModel2.js"></script>

    <!-- App scripts -->
    <script src="js/routes.js"></script>
    <script src="js/app.js"></script>
</body>

html文件有一个div,它将保存Sammy.js处理的每个相应页面的html,其代码如下:

Sammy('#main', function() {

    this.get('#/', function(context) {
        context.$element().load('views/main1.html', function() {
            ko.applyBindings(new ViewModel1(), $("#home")[0]);
        });
    });

    this.get('#/text', function(context) {
        context.$element().load('views/text.html', function() {
            ko.applyBindings(new ViewModel2(), $("#home")[0]);
        });

    });

    this.get('', function(context) {
        this.redirect('#/');
    });

}).run();

每次我加载每个html文件中找到的标记,然后应用我的viewmodel。

我的问题是:

  1. 除了使用jquery load()之外,您能否建议任何其他可能的加载标记的方法。
  2. 每次调用新路线时,我的旧绑定是否被处理?

1 个答案:

答案 0 :(得分:1)

1:这个问题非常“开放”。有很多方法可以做到这一点jquery.load。但真正的问题是:你还需要另一种方式吗?你需要$.load没有给你的某种形式的控制吗? 如果您这样做,请考虑切换到jquery.getjquery.ajax,并自行处理请求。在这篇文章的底部是一个例子。

2:不,因为你继续将绑定应用于同一个元素。您想要做的是将绑定应用于ID为'home'的容器中的第一个元素。然后,当您切换视图时,您希望在要删除的视图上执行ko.removeNode。下面是一个代码示例,说明如何获得对该过程的更多控制并清理您身后的绑定。

function loadView(url, viewModel) {
    $.get(url, function (response) {
        var $container = $('#home'),
            $view = $container.find('.view'),
            $newView = $('<div>').addClass('view').html(response);
        if ($view.length) {
            ko.removeNode($view[0]); // Clean up previous view
        }
        $container.append($newView);
        ko.applyBindings(viewModel, $newView[0]);
    });
}
this.get('#/', function(context) {
    loadView('views/main1.html', new ViewModel1());
});
this.get('#/', function(context) {
    loadView('views/text.html', new ViewModel2());
});

我在此示例中所做的是使用jquery.get,因此我们可以控制加载和显示HTML的整个过程。然后,我将部分逻辑重构为一个单独的函数,该函数足够通用,可用于您拥有的每个视图。 检索视图时,我将其存储在具有“视图”类的元素中。绑定应用于此元素,并存储在容器元素中。在切换视图时,我会在将新视图添加到DOM之前清理并删除旧视图。

这只是一个开始:在loadView函数中,您现在可以尝试调用可以在视图模型上实现的泛型方法,例如“activate”和“deactivate”。您还可以在检索新视图时显示微调器而不是视图等。