RequireJS在加载完成的所有内容之前不会隐藏KnockoutJS绑定

时间:2015-04-15 18:07:09

标签: javascript knockout.js requirejs

TL;博士

我看到的问题是我的初始页面(Index.cshtml)有一些Knockout代码(indexViewModel.js)被调用,最初在加载时隐藏div,但是对于一些短暂的div确实隐藏b / c Knockout代码尚未评估。

<小时/>

背景&amp;问题

我刚刚开始重构我的网站以使用 RequireJS 。它是一个ASP.NET MVC 5应用程序,它使用KnockoutJS,jQuery和一些jQuery&amp; amp; JavaScript插件。

在RequireJS重构之前,一切都很有效。现在,当用户加载索引时,向用户显示微调器(data-bind="showSpinner"为false)大约3秒钟,然后加载Knockout代码并意识到它应该被隐藏,然后隐藏它。

所以我想知道如何防止这种情况&#34;闪烁&#34;隐藏的元素发生了什么?在Angular中你可以ng-cloak,但我还没有找到Knockout或Require的等价物。

我知道在加载所有模块之前我最初可以隐藏一些东西,但是我不想破解我的整个应用程序,因此默认情况下隐藏了这些内容。

我的代码

这是我的网站的基本设置,使用RequireJS,Knockout,jQuery和&amp; ASP.NET MVC。

Index.cshtml

<div data-bind="showSpinner">
    <img src="/Content/spinner.gif" />
</div>

<!-- at the bottom of my Index.cshtml I have this section below 
    which renders the script at the very bottom of the entire DOM, via
    ASP.NET MVC `render scripts`-->

@section scripts 
{
    <script>
        var d = @Html.Raw(Json.Encode(Model));
        require( [ "/Scripts/app/common.js" ], function() {
            require( [ "app/offers/index"], function(view) {
                view.init(d);
            });
        });
    </script>
}

common.js

require.config({
    baseUrl: "/Scripts/",
    paths: {
        "jquery": "jquery-1.11.2",
        "underscore": "underscore.min",
        "knockout": "knockout-3.3.0.debug",
        "komapping": "knockout.mapping-latest",
        "noUiSlider": "jquery.nouislider.all",
        "bootstrap": "bootstrap" 
    },
    shim: {
        "komapping": {
            deps: ['knockout'],
            exports: 'komapping'
        },
        "noUiSlider": {
            deps: ["jquery"],
            exports: '$'
        },
        "bootstrap": {
            deps: ["jquery"]
        }
    }
});

index.js

define(['knockout', 'app/offers/indexViewModel'], function (ko, mvm) {
    return {
        init: function (modelData) {
            var vm = modelData;
            mvm.addMethods(vm);
            ko.applyBindings(vm);
        }
    };
});

indexViewModel.js

define(['knockout', 'jquery'], function (ko, $) {
    return {

        addMethods: function (viewModel) {
            viewModel.showSpinner = ko.observable(false);
            //then a bunch of other KO code, but that observable above is the first thing & i use some jQuery plugins below, that's why i load in jQuery
        }
    };
});

1 个答案:

答案 0 :(得分:4)

尝试将内容标记为“display:none;”在样式表或内联样式中。然后使用Knockout的“可见”绑定来控制可见性。内容将被隐藏,直到Knockout有机会评估,将可见性设置为您的Knockout逻辑所指示的内容。

RequireJS可能是异步加载脚本,所以在JavaScript有机会执行之前标记就会呈现。因此,在JavaScript执行之前,您需要一种同步方式来隐藏内容。

ngCloak使用完全相同的技巧:有一个CSS选择器隐藏任何带有ngCloak属性的元素,直到Angular的JavaScript有机会执行。

https://docs.angularjs.org/api/ng/directive/ngCloak