javascript - 同步组件注册

标签 javascript knockout.js

我有一个 knockout 组件,看起来像这样:

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 函数订阅更新事件,稍后我将使用该事件来触发其他组件对组件 View 模型的更新。

我将组件包含在我的页面上,如下所示:

<!-- ko component: "my-component" -->
<!-- /ko -->

我想要验证的是事物的加载顺序。我想确保在触发事件之前已调用 createViewModel

这是我当前的调用顺序:

// register my-component here
ko.applyBindings(myMainViewModel);
// code that might trigger the component update event here

我读到 ko.applyBindings 是同步的。但这是否还包括对所有已注册组件的隐式 applybindings ,如上面的 my-component ?我是否需要将组件上的 synchronous 属性设置为 true 才能实现此目的?如果我理解正确的话,该标志仅与渲染相关。

我想避免的是在订阅更新事件之前触发更新事件的竞争条件。

最佳答案

如果在调用之前满足以下条件,ko.applyBindings 可以同步 Action :

  1. 所有组件均已注册
  2. 所有组件 View 模型都加载到内存中(从网络获取......)
  3. 所有组件模板均加载到内存中

当组件 View 模型和模板不在内存中时,applyBindings 就会变为异步(如果设置 synchronous=true,则会发生事件)。

此同步标志在 component binding 的 applyBindings 中发挥作用。 。请注意,组件绑定(bind)执行 ko.components.get 调用并传递一个回调,该回调将在 DOM 上呈现组件。

knockout/src/components/loaderRegistry.js具有 ko.components.get 的定义。同步标志表示,如果组件已经缓存(在内存中),则不要放弃对线程的控制。只有当您释放对线程的控制(setTimeout、DOM 插入/等待等)时,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
})

这几乎没有什么问题,而且所有问题都有解决方案。

  1. 需要等待多个组件完成加载

    [要解决这个问题,您可以为每个组件创建一个 Promise 数组,并通过 ko.components.get 解析每个组件。最后你可以 $.when(mypromiseArray, myCallback) 来同步所有的 Promise]

  2. ko.component.get 不会告诉您组件何时最终呈现在 DOM 上。

    这是一个更具挑战性的问题。如果您需要这种精度(您需要在 50 毫秒内知道组件何时加载并在 UI 上呈现),我将分享解决方案。

关于javascript - 同步组件注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35392138/

相关文章:

Javascript 循环中的回调函数

javascript - 如何在 svelte 项目中配置 sass 和 ESLint?

javascript - 如何访问同一 viewModel 中不同分支的后代?

javascript - 异步 knockout observableArray 选择选项加载

javascript - Knockout.js 在 foreach 绑定(bind)中绑定(bind)选择选项和值

javascript - 如何动态设置ng-model

javascript - 如何使用 XMLHttpRequest 示例格式化 request.get

javascript - JS 根据键/值对设置 var 值,其中键等于 var 名称

knockout.js - 使用 Durandal 的应用架构

javascript - Knockout.js 跟踪选中的复选框