【问题标题】:KnockoutJS with Sammy.js SPA suggestion带有 Sammy.js SPA 建议的 KnockoutJS
【发布时间】:2014-05-05 20:48:12
【问题描述】:

我正在构建一个具有以下结构的 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 文件中找到的标记,然后应用我的视图模型。

我的问题是:

  1. 除了使用 jquery load() 之外,您能否建议任何其他可能的方式来加载标记。
  2. 是否每次调用新路由时都会释放我的旧绑定?

【问题讨论】:

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


    【解决方案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 函数中,您现在可以尝试调用可以在视图模型上实现的通用方法,例如“激活”和“停用”。您还可以在检索新视图时显示微调器而不是视图等。

    【讨论】:

    • 感谢您的回复。有些事情现在很清楚了。 $('home')[0] 实际上是我调用的每个 html 文件中的第一个元素,如下所示:
      现在点击我
      每次我将上述标记添加到 id 为“main”的 div 中。因此,我假设使用上面的代码,我会在调用 load 方法之前调用 removeNode。
    猜你喜欢
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 2016-04-11
    • 1970-01-01
    • 2014-08-01
    • 2018-05-16
    • 1970-01-01
    相关资源
    最近更新 更多