隐藏页面直到 Knockout 绑定和所有子绑定完成

Hide page until Knockout binding and all sub bindings are finished

我有一个页面有一个淘汰赛模型,淘汰赛模型里面有这样的子模型:

  function firstSubViewModel(listData) {
         var self = this;
         self.myAttribute = ko.observable();
         function that sets stuff()
         return self;
 }

var MyViewModel = function () {
        var self = this;
        // load the sub-viewmodels used on the page
        self.foo= new firstSubViewModel(params);
        self.bar= new secondSubViewModel(otherparams);
}
vm = new MyViewModel();
ko.applyBindings(vm);

这只是伪代码,实际上有一堆子模型,每个子模型都有一堆自己的属性和其他被调用的函数。 我想首先隐藏该页面,然后当所有子模型的所有数据都在时,我将显示主页。到目前为止,我已经尝试设置:

<div id = "main" style = "display: none" data-bind = "visible: true"></div>

这将隐藏页面,直到主模型被绑定然后显示它。但是,如果任何子模型需要一段时间才能加载,则在显示页面时它们不会完成,例如,如果该属性未填充,子模型中基于 myAttribute 的图像将不会加载。所以我可以解决这个问题。

<div id = "main" style = "display: none" data-bind = "visible: vm.foo.myAttribute"></div>

就是说要等到有值才显示页面,但是我有一堆带有一堆属性的子模型,这样说有点可笑

  <div data-bind = "visible:vm.foo.myAttribute && vm.bar.myAttribute && vm.bar.otherAttribute && etc.."></div>

有没有一种更简洁的方式来观察和等待所有这些都被填充?

解决方法很简单。在您的主视图模型上有一个可观察对象,当所有工作完成时它会变成 true

<div id="main" style="display: none" data-bind="visible: allDone"></div>

function MainViewModel() {
    var self = this;

    self.foo = ko.observable();
    self.bar = new SubModel();
    // all other observables and sub-viewmodels here

    self.allDone = ko.computed(function () {
        // now just subscribe to all kinds of observables
        var foo = self.foo(),
            bar = self.bar.myAttribute();

        // ...and do value checks
        return foo > "" && bar > "";
    });
}

Knockout 将在订阅的属性进入时更新 allDone,并且在某个时间点,总体 return 值将为真。

尽管公认的解决方案有效,但我找到了一种更简单的方法来完成此任务(至少对我有用)。

<div id="content" style="display: none" data-bind="style: {display: 'block'}">
    <!-- YOUR CONTENT HERE -->
</div>

在 Knockout 加载之前,使用初始样式,在本例中显示 none。但是一旦 Knockout 完成加载视图模型,数据绑定中的样式就会执行。