首页 > 解决方案 > 测试期间未触发 Marionette onAttach 生命周期

问题描述

我正在编写测试,其中我在 onAttach 生命周期方法中有一些逻辑,但是在测试时永远不会调用 onAttach。

这就是我最初尝试测试它的方式

 beforeEach(() => {
        view = new OffersTab();
        view.render();
 });

但我的理解是,当显示区域时它 onAttach 会被触发,所以我尝试这样做,

beforeEach(() => {
    let parentView = new AllOffers();
    parentView.render();
    parentView.getRegion('offersTab').show(new OffersTab());

    view = parentView.getRegion('offersTab');
});

但是 onAttach 仍然没有触发,让我无法编写测试

标签: javascriptbackbone.jsjasminemarionette

解决方案


视图上的事件和区域上的attach事件之间存在差异。(该方法是一种方便的方法,不需要订阅。)showonAttachlistenTo

attach当您的视图显示在一个区域中时触发该事件,这会将视图附加到 DOM - 到其祖先位于页面document( document.documentElement) 中的元素。这意味着视图的元素 ( el) 或父视图或祖先视图已附加到 DOM。在父视图的区域中显示视图是不够的。首先,当该父视图附加到 DOM 时,该事件将递归触发到所有子视图。

parentView在显示子视图之前,您可以通过 testing 来检查它:

// All will return false
document.documentElement.contains(parentView.el);
Marionette.isNodeAttached(parentView.el);
parentView.isAttached();

如果您的视图需要附加到 DOM 才能正常工作,您必须选择 DOM 中的一个元素并在其中显示父视图。例如,在document.body

let body, parentView, view;

before(() => { // mocha's "before all"
  body = new Marionette.Region({ el: 'body' });
});

beforeEach(() => {
  parentView = new AllOffers();
  body.show(parentView); // attach the parent view to DOM

  view = new OffersTab();
  parentView.getRegion('offersTab').show(view);
});

afterEach(() => {
  body.empty(); // detach and destroy the view
});

或者,您可以将AllOffers附加到 DOM 本身作为其代码。或者将 DOM 中的元素传递给它的构造函数,例如:new AllOffers({ el: body }). 不要记得在不需要时销毁它。

节目

当视图显示在区域中时,该事件将在区域show上触发,而不是在视图上。(我写的是 Marionette 3 或更新版本。Marionette 2 触发了视图上的事件。)show

如果您的事件处理程序需要在父视图的区域中显示视图后立即执行,而不是在视图出现在 DOM 之后,请考虑将您的代码移动到render事件(或onRender方法)。您可以收听show该区域的事件并在您的子视图中重新触发它,但您最好遵循 Marionette 的最佳实践并使用其他事件


推荐阅读