谷歌浏览器和互联网浏览器不同

时间:2016-11-17 09:29:05

标签: javascript google-chrome internet-explorer knockout.js requirejs

我的应用程序使用knockout.js自定义元素。视图模型和模板的加载顺序在Google Chrome和Internet Explorer中不同。

在我的网络应用程序中,我定义了许多自定义元素,如:


   ko.components.register('account-management-me', {
        viewModel: {  require: 'Scripts/app/components/accountManagementMe/ViewModel' },
        template: { require: 'text!Scripts/app/components/accountManagementMe/' + language + 'View.html' }
    });

使用Internet Explorer,我观察到以下加载顺序:

  
      
  1. ViewModel.js
  2.   
  3. enView.html
  4.   

使用Chrome我观察到以下加载顺序:

  
      
  1. enView.html
  2.   
  3. ViewModel.js
  4.   

因此,来自ViewModel.js的视图中绑定的字段未定义,并且淘汰会抛出异常。

有没有办法影响加载顺序?

1 个答案:

答案 0 :(得分:2)

  

有没有办法影响加载顺序?

是的,如果您将组件注册为单个模块as shown in the documentation,那么您可以将其设置为使视图模型依赖于您的模板,因此您的模板将始终在视图模型之前加载。< / p>

Knockout正在使用RequireJS加载视图模型和模板。如文档中所述,它会发出一个简单的require调用,并将模块命名为ko.components.register。对于您的代码,等效的require调用将是:

require(['Scripts/app/components/accountManagementMe/ViewModel'], callback);
require(['text!Scripts/app/components/accountManagementMe/enView.html', callback);

这两个调用无法约束加载顺序。 .../ViewModel是第一个并不重要。 (实际上,它可能是第二个。)两个调用都是异步的,并且可以按任何顺序解析,除非模块使用define来建立一个的依赖关系。这就是RequireJS的工作原理。没有明确的依赖关系,订单是不确定的,并且可能因浏览器内部,网络条件等而有所不同。

要将您的组件注册为单个模块,您可以:

ko.components.register('account-management-me', 
  { require: 'Scripts/app/components/accountManagementMe/ViewModel' });

上面提到的模块包含类似的内容:

define(['knockout', 'text!Scripts/app/components/accountManagementMe/enView.html'], function(ko, template) {
    function ViewModel() {
    }

    ViewModel.prototype.foo = function() { ... };

    return { viewModel: ViewModel, template: template };
});

在这个例子中,我已经将模板模块名称设为静态字符串。您希望根据配置的语言加载不同的模板,但不支持将运行时计算的字符串放在define的依赖项中。你可以使它适用于一些微不足道的情况,但如果你想用r.js来优化你的模块,它会阻塞计算字符串。要获得语言支持,您应该使用i18n plugin。或者提供类似功能的东西。关于如何使用它有很多问题,如果你在设置i18n时遇到麻烦,你可以看一下。