Get async view model to component

2019-08-08 19:07发布

I would like to fetch a view model from the server and use it in my component. Is it possible? My attempt, which obviously doesn't work:

function getDummyViewModelAsync(){
   setTimeout(function(){
       cb({ foo: 1 });
   }, 500);
}

ko.components.register('my-component', {
   viewModel: {
       createViewModel: function(params, componentInfo) {

           getDummyViewModelAsync(function(viewModel){
               return viewModel;
           });
       }
   },
   template: ...
});

1条回答
Lonely孤独者°
2楼-- · 2019-08-08 20:06

It's not clear from our exchange in the comments what you are trying to do that cannot be done with the dynamic-loading modules. You can load your module structure dynamically, and of course you can populate elements of it dynamically.

If you want to do everything by hand instead, you can do that. Pass your viewmodel to the fetching function. Have the fetching function return a promise, and resolve it when it has fetched the data and put it in the viewmodel. Your template can even dynamically reference other templates, so you see one thing while loading and another when done.

function getDummyViewModelAsync(populateMe) {
  return new Promise(
    function(resolve, reject) {
      setTimeout(function() {
        populateMe.cb = ko.observable('A value');
        resolve('whatever');
      }, 500);
    }
  );
}

ko.components.register('my-component', {
  viewModel: {
    createViewModel: function(params, componentInfo) {
      var vm = {
          template: ko.observable('loading'),
          ready: ready
        },
        ready = getDummyViewModelAsync(vm);
      ready.then(function() {
        vm.template('ready');
      });
      return vm;
    }
  },
  template: document.getElementById('selector').innerHTML
});

console.clear();
ko.applyBindings();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<template id='loading'>
  Loading...
</template>
<template id='ready'>
  Ta da!
  <div data-bind="text: cb"></div>
</template>
<template id='selector'>
  <!-- ko template: template -->
  <!-- /ko -->
</template>

<my-component></my-component>

查看更多
登录 后发表回答