如何在没有viewmodel的页面上加载组件?

时间:2016-12-20 00:17:21

标签: knockout.js

我知道ko.applyBindings()可以将视图模型和元素作为参数。但我有一个没有viewmodels的页面。我不想在页面加载时加载/运行组件,而是单击,因为组件依赖于click事件传入的数据。

ko.applyBindings()置于click事件监听器中可以正常工作但是有更好的方法吗?

编辑: 我有一个模态组件,我不想在页面加载时加载/运行,但是点击是因为组件依赖于click事件传入的数据。

在点击事件监听器中放置ko.applyBindings()在第一次点击时工作正常,如果模态已关闭并再次重新打开,它将会中断。

// This runs on click

var init = function(options) {
  var viewModel = options; // options is an object

  ko.applyBindings(viewModel, document.querySelector('.modal-container'));

  if (options.category) {
    ko.postbox.publish('isVisible', true);
  }
}


// The component

(function() {
  'use strict';

  var viewModel = {
    createViewModel: function() {
      var state = {
        isVisible: ko.observable(false).subscribeTo('isVisible')
      };

      state.isVisible.subscribe(function(visible) {
        if (visible) {
          // some code to open the modal
        }
      };

      return {
        state: state
      };
    }
  };

  ko.components.register('modal', {
    viewModel: viewModel,
    template: { element: 'tpl-modal' }
  });
})();


// The view
<div class="modal-container">
  <modal></modal>
</div>

<template id="tpl-modal">
  <div data-bind="visible: state.isVisible">
    Modal content
  </div>
</template>

问题:

1:无法重新打开模态,多重绑定错误。

2:组件内部的`isVisible不会从邮箱中获取新值(在init函数中发布/触发)。

3:如何访问在模态组件中ko.applyBindings传入的viewModel?

1 个答案:

答案 0 :(得分:0)

ko.applyBindings接受两个参数:第一个是viewmodel,第二个是要绑定的节点。如果您只想在文档的某个区域绑定组件,则应将该元素传递给ko.applyBindings

如果需要更改应用于元素的viewmodel,则应使用可观察的viewmodel。

var componentVM = ko.observable();  // declared in a persistent location (not in the click handler)

// In the click handler, create your viewmodel (let's call it vm)
// Then set the observable, but only bind it the first time
if (!componentVM()) {
    // set observable and bind to node
    componentVM(vm);
    ko.applyBindnigs(componentVM, nodeToBind);
} else {
    // update observable with new vm
    componentVM(vm);
}