Skip to content

will-destroy does not invoke re-rendering #18

@LordCHTsai

Description

@LordCHTsai

This happened when I tried to write a HOC with a parent passing a function to its child, and the function gets called when the child is inserted and going to be destroyed. I made an integration test to demonstrate the issue.

import Component from '@glimmer/component';
import { click, find, render } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { action } from '@ember/object';
import hbs from 'htmlbars-inline-precompile';
import { setupRenderingTest } from 'ember-qunit';
import { tracked } from '@glimmer/tracking';

module('Integration | Modifier | will-destroy', hooks => {
  setupRenderingTest(hooks);

  test('it should invoke UI re-rendering when changing tracked properties', async function(assert) {
    this.owner.register(
      'component:parent-component',
      class extends Component {
        @tracked text = '';

        get message() {
          return this.text;
        }

        @action changeText(text) {
          this.text = text;
        }
      }
    );

    this.owner.register(
      'template:components/parent-component',
      hbs`
        <div data-dummy>{{this.message}}</div>
        {{yield (hash changeText=this.changeText)}}
      `
    );

    this.set('show', true);

    await render(
      hbs`
        <ParentComponent as |parent|>
          {{#if show}}
            <div
              {{did-insert (fn parent.changeText "Hello")}}
              {{will-destroy (fn parent.changeText "World")}}
            >
            </div>
          {{/if}}
          <button data-button {{on "click" (fn parent.changeText "World")}}>Change Text</button>
        </ParentComponent>
      `
    );

    // did-insert invokes re-rendering correctly, now the message is "Hello".
    assert.strictEqual(find('[data-dummy]').innerText, 'Hello'); 

    // trigger destroying. should change text.
    this.set('show', false);

    // will-destroy does not invoke re-rendering. message supposed to be "World".
    assert.strictEqual(find('[data-dummy]').innerText, 'Hello'); 

    await click('[data-button]');
    // if the changeText function is called by other ways, it works seamlessly.
    assert.strictEqual(find('[data-dummy]').innerText, 'World');
  });
});

Also attached some dependencies info here.

"devDependencies": {
  "@ember/optional-features": "^0.7.0",
  "@ember/render-modifiers": "^1.0.2",
  "@glimmer/component": "^0.14.0-alpha.13",
  "ember-cli": "~3.13.1",
  "ember-cli-babel": "^7.7.3",
  "ember-source": "~3.13.2"
},

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions