我的应用程序使用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,我观察到以下加载顺序:
- ViewModel.js
- enView.html
醇>
使用Chrome我观察到以下加载顺序:
- enView.html
- ViewModel.js
醇>
因此,来自ViewModel.js
的视图中绑定的字段未定义,并且淘汰会抛出异常。
有没有办法影响加载顺序?
答案 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时遇到麻烦,你可以看一下。