有没有办法异步初始化 Viewmodel (KnockoutJS)

Posted

技术标签:

【中文标题】有没有办法异步初始化 Viewmodel (KnockoutJS)【英文标题】:Is there a way to asynchronous initialize a Viewmodel (KnockoutJS) 【发布时间】:2021-06-09 08:00:06 【问题描述】:

我想异步初始化一个 ViewModel。我不是指异步加载 ViewModel,我已经管理了(见下面的代码)。

ViewModel 将被异步加载一次。之后,我想根据提供给 ViewModel 的参数做一些异步操作。看起来在获得参数后,您必须同步返回 ViewModel,不支持承诺/回调系统。 请看下面的代码:


const defaultLoader: KnockoutComponentTypes.Loader = 
  loadViewModel: function (name, templateConfig, callback) 

    //if there is a 'fromUrl' property
    if (templateConfig.fromUrl) 

      //use import to load the code 
      import(templateConfig.fromUrl)
        .then(module => 

          //viewmodel is loaded asynchronous (one time!)
          callback( (params, componentInfo) => 
            
            //initialize the viewModel
            const model = module.default(
              params,
              componentInfo)
          
              //I can only return synchronously here:
            return model
          );
        )
     
  


我想做的是使用 async/await 来表示它必须在一切解决之前等待:

          //ViewModel is loaded asynchronous (one time!)
          callback(async (params, componentInfo) => 

            //initialize the viewModel
            const model = module.default(
              params,
              componentInfo)

            //I can only return synchronously here:
            return await model
          );

但是我的 ViewModel 最终成为了 Promise 对象。 关于如何实现这一点的任何建议?

【问题讨论】:

【参考方案1】:

您不能从异步函数返回任何内容,但这与 Knockout 无关。你可以返回一个 Promise,或者在你的异步函数中调用其他函数。

为此,您应该能够在完成处理后使用 KO 的默认加载器(不要覆盖它,就像您现在正在做的那样)来创建视图模型,如下所示:

const customLoader: KnockoutComponentTypes.Loader = 
    loadViewModel: function(name, templateConfig, callback) 

        //if there is a 'fromUrl' property
        if (templateConfig.fromUrl) 

            //use import to load the code 
            import(templateConfig.fromUrl)
                .then(module => 

                    //viewmodel is loaded asynchronous (one time!)
                    callback((params, componentInfo) => 

                        //initialize the viewModel
                        const model = module.default(
                            params,
                            componentInfo)

                        ko.components.defaultLoader.loadViewModel(name, model, callback);
                    );
                )
        
    

【讨论】:

我尝试了你的建议。但这行不通。我确实可以在“导入”之后使用默认加载器。但不在回调函数内部。在那里,您将回调传递给 defaultloader,但您已经在执行它。我理解你关于异步函数的观点,但看起来 Knockout 只是将 promise 作为视图模型,并且没有任何东西可以等待。

以上是关于有没有办法异步初始化 Viewmodel (KnockoutJS)的主要内容,如果未能解决你的问题,请参考以下文章

MvvmCross ViewModel启动方法异步行为澄清

等待模块导入异步初始化的最佳方法?

使用没有ViewModel的Room

从 ViewModel 构造函数 Xamarin.Forms 调用异步方法

Android ViewModel 不断初始化 ArrayList

在 viewmodel 的构造函数中调用异步方法加载数据有警告