我有一个淘汰组件,看起来像这样:
define(['knockout', 'text!./my-component.html', 'pubsub'], function(ko, htmlString, pubsub) {
function viewModel(params) { }
return {
viewModel: {
createViewModel: function(params, componentInfo) {
var vm = new viewModel(params);
pubsub('updateViewModel').subscribe(function(){
// update vm
});
return vm;
}
},
template: htmlString
};
});
我使用createViewModel
函数订阅更新事件,我稍后会使用它来触发其他组件更新组件viewmodel。
我在我的页面上包含了这样的组件:
<!-- ko component: "my-component" -->
<!-- /ko -->
我想要验证的是事物的加载顺序。我想确保在之前调用了<{1}}我可能会触发事件。
这是我目前的电话订单:
createViewModel
我已经读过// register my-component here
ko.applyBindings(myMainViewModel);
// code that might trigger the component update event here
是同步的。但是,这还包括对所有已注册组件的隐式ko.applyBindings
,例如上面的applybindings
吗?我是否需要在组件上将my-component
属性设置为synchronous
才能实现此目的?如果我理解正确,那个标志只与渲染有关。
我想避免的是竞争条件,我在订阅之前触发更新事件。
答案 0 :(得分:2)
ko.applyBindings可以同步操作:
当组件视图模型和模板不在内存中时,applyBindings变为异步(如果设置了synchronous = true,则为事件)。
这个同步标志可以在component binding的applybinding中播放。请注意,组件绑定执行ko.components.get
调用并传递回调,这将在DOM上呈现组件。
knockout/src/components/loaderRegistry.js的定义为ko.components.get。同步标志表示如果组件已经缓存(在内存中),则不要放弃对线程的控制。它只有当你释放对线程的控制(setTimeout,DOM insert / wait,..)时才会返回applyBindings。
我唯一不太确定的是RequireJS将如何在这里互动。 knockout中有代码会尝试先使用require来解析组件。
在任何情况下,以下步骤都会让您更接近(不完美。请参阅下面的注释)
//Load component vm, template and register it with synchronous=true
ko.appplyBinding(....)
ko.components.get("my-component" , function() {
//trigger component update event
})
这方面的问题很少,而且所有这些都有解决方案。
需要等待多个组件完成加载
[为了解决这个问题,你可以为每个组件创建一个promise数组,并通过ko.components.get解析每个组件。最后你可以$ .when(mypromiseArray,myCallback)同步所有的承诺]
ko.component.get不会告诉您何时最终在DOM上呈现组件。
这是一个更具挑战性的问题。如果您需要这种级别的精度,我将分享解决方案(您需要在50ms内了解组件何时加载并在UI上呈现)。