问题描述
在ko.applyBindings()调用之后,是否可以应用组件绑定?
Is there a way to apply component bindings after the ko.applyBindings() call?
重点是,我使用requireJS异步加载我的模块/组件.那么我怎么知道所有绑定都已注册?
The point is, I use requireJS to load my modules/components async. So how do I know that all bindings are registered?
ko.applyBindings();
ko.components.register('my-component',
{
viewModel: function() {
this.name = ko.observable('My Name');
},
template: '<input type="text" data-bind="value: name"></input>'
}
);
// Moving it here, it works:
// ko.applyBindings();
推荐答案
您可以使用以下几项来动态地了解和加载组件.
There are a couple of pieces that you could use to dynamically understand and load components.
1-一个自定义组件加载器
您可以创建一个组件加载器,该加载器可以从组件名称中了解需要哪些文件.
You could create a component loader that understands from a component name, which files to require.
举个例子,假设任何以my-
开头的组件,我们都希望按照惯例从components
目录中进行.
For sake of an example, lets say that any component that starts with my-
, we want to require from the components
directory by convention.
它看起来像:
//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
});
如果默认的加载器找不到组件(尚未注册),则可以启动该组件.
If the default loader can't find a component (not registered yet), then this one would kick in.
2-我们仍然需要处理自定义元素,取消注册.该文档描述了ko.components.getComponentNameForNode
方法,可以将其覆盖以将元素标签动态转换为组件名称.
2- We would still need to handle custom elements, as these run off of the registration as well. The documentation describes the ko.components.getComponentNameForNode
method that could be overriden to dynamically convert an element tag to component name.
在我们的例子中,它看起来像:
In our case, this could look like:
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/
Here is a fiddle that puts these together with require.js: http://jsfiddle.net/rniemeyer/tgm8wn7n/
还要注意IE6-8警告此处,因为它会影响动态了解自定义元素.
Also, take note of the IE6-8 warning here, as it would affect dynamically understanding the custom elements.
或者,您需要确保在将组件绑定到UI之前已注册所有组件(不一定在初始applyBindings时,而是在遇到需要绑定的组件时)
Alternatively, you would need to ensure that all of your components are registered before that component is bound in the UI (not necessarily at the time of the initial applyBindings, but as soon as a component is encountered that needs to be bound).
这篇关于调用ko.applyBindings()后如何应用组件绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!