ember js дочерний компонент не перерисовывается после обновления свойства - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть компонент страницы (пять белов) с количеством входов, которые пользователь может выбрать для завершения ввода. Когда пользователь нажимает кнопку «Завершить», все вопросы отключаются.

Компонент страницы

five-whys.hbs:

{{#each this.whys as |why i|}}
  <Generic::RichTextInput
    @value={{why.content}}
    @onChange={{action this.whyChanged i}}
    @disabled={{this.isFinalized}} />
{{/each}}
<button {{on "click" this.finalizeWhy}}>Finalize</button>

five-whys.ts

interface AnalyzeFiveWhysArgs {
  dataStory: DataStory;
}

export default class AnalyzeFiveWhys extends Component<AnalyzeFiveWhysArgs> {
  @alias("args.dataStory.fiveWhysAnalysis") fiveWhysAnalysis

  @tracked
  isFinalized: boolean = this.fiveWhysAnalysis.isFinalized ?? false;

  @tracked
  whys: LocalWhy[] = this.fiveWhysAnalysis.whys;

  @tracked
  isFinalized: boolean = this.fiveWhysAnalysis.isFinalized ?? false; 

  @action
  async finalizeWhy() {
    this.isFinalized = true;
  }

Это прекрасно работает, когда мой текстовый компонент представляет собой обычную текстовую область. Тем не менее, я пытаюсь реализовать tinymce, который требует от меня делать что-то за пределами Embers, маленькое безопасное пространство для магов c.

Мой компонент расширенного текста:

Шаблон:

<textarea id={{this.id}} disabled={{this.templatePieceIsDisabled}}>{{@value}}</textarea>

Машинопись:

interface GenericRichTextInputArgs {
  value?: string;
  onChange: (value: string) => void;
  name: string;
  disabled?: boolean;
}

export default class GenericRichTextInput extends Component<GenericRichTextInputArgs> {
  constructor(owner: unknown, args: GenericRichTextInputArgs) {
    super(owner, args);

    this.initializeTinymce();
  }

  id = this.args.name;

  get editor() {
    return tinymce.get(this.id);
  }

  get settings() {
    console.log(this.args.disabled);

    const settings: TinyMCESettings = {
      selector: `#${this.id}`,
      setup: (editor: Editor) => this.setupEditor(this, editor),
      readonly: this.args.disabled ? this.args.disabled : false
    };
    return settings;
  }

  initializeTinymce() {
    Ember.run.schedule('afterRender', () => {
      console.log("re-initializing"); // I expect to see this log every time the isFinalized property in the five-whys component changes. But I only see it on page load.

      tinymce.init(this.settings);
    });
  }

  setupEditor(self: GenericRichTextInput, editor: Editor) {
    ... // details of tinymce API
  }
}

Когда я нажимаю кнопку финализации, эффект флага отключения в компоненте форматированного текста не меняется.

Примечание:

Библиотека tinymce, которую я использую, устанавливает отображение текстовой области на none, а aria-hidden - на true. Это потому, что он оборачивает текстовое поле в виджет. Поэтому я должен использовать API библиотеки для отключения.

1 Ответ

0 голосов
/ 06 апреля 2020

Я понял это. Ember не запускает конструктор для события жизненного цикла обновления. Поэтому мне нужно сказать Ember перезапустить инициализатор при повторной визуализации шаблона. Мне пришлось использовать https://github.com/emberjs/ember-render-modifiers для этого.

Так что мой шаблон текстового редактора выглядит так:

<textarea
  id={{this.id}}
  {{did-update this.updateDisabled @disabled}}>
  {{@value}}
</textarea>

И я добавил это действие в коде редактора форматированного текста:

  @action
  updateDisabled(element: HTMLTextAreaElement, [disabled]: any[]) {
    this.disabled = disabled;

    this.editor.destroy();
    this.initializeTinymce();
  }
...