您可以使用几个部分来动态理解和加载组件。
1-自定义组件加载器
您可以创建一个组件加载器,它可以从组件名称中理解需要哪些文件。
举个例子,假设任何以 开头的组件my-
,我们希望按照components
约定从目录中获取。
它可能看起来像:
//add a loader to the end of the list of loaders (one by default)
ko.components.loaders.push({
getConfig: function(name, callback) {
var widgetName;
//see if this is one of our widgets
if (name.indexOf("my-") > -1) {
widgetName = name.substr(3).toLowerCase();
//provide configuration for how to load the template/widget
callback({
require: "components/" + widgetName
});
} else {
//tell KO that we don't know and it can move on to additional loaders
callback(null);
}
},
//use the default loaders functionality for loading
loadComponent: ko.components.defaultLoader.loadComponent
});
如果默认加载器找不到组件(尚未注册),那么这个加载器就会启动。
2-我们仍然需要处理自定义元素,因为这些元素也需要注册。该文档描述了ko.components.getComponentNameForNode
可以被覆盖以将元素标签动态转换为组件名称的方法。
在我们的例子中,这可能看起来像:
var existingGetComponentNameForNode = ko.components.getComponentNameForNode;
ko.components.getComponentNameForNode = function(node) {
var tagNameLower = node.tagName && node.tagName.toLowerCase();
//if we found one of our tags, then use it as the component name
if (tagNameLower.indexOf("my-") > -1) {
return tagNameLower;
}
// call the original
return existingGetComponentNameForNode.apply(this, arguments);
};
这是一个将这些与 require.js 放在一起的小提琴:http: //jsfiddle.net/rniemeyer/tgm8wn7n/
另外,请注意此处的 IE6-8 警告,因为它会影响动态理解自定义元素。
或者,您需要确保在 UI 中绑定该组件之前注册所有组件(不一定在初始 applyBindings 时,而是在遇到需要绑定的组件时)。