Aurelia 在 repeat.for 之前附加触发器

Aurelia attached triggers before repeat.for

我正在尝试在 Aurelia 中设置某些逻辑,这会影响 DOM 由 repeat.for 循环的节点。如果我对文档的理解正确,视图的 attached() 回调在 DOM 渲染之后调用,并且是放置这种逻辑的地方。

问题是 attached() 回调似乎在 repeat.for 绑定完成之前被触发,只剩下部分渲染的 dom.

为了说明问题:

我有一个自定义元素包含:

<template>
    <ul>
      <li repeat.for="thing of things"></li>
    </ul>
</template>

一旦调用了 attached(),我希望呈现的 DOM 包含所有 li 元素。 dom 的简单转储显示空

如何实现回调以访问那些 li 节点?

attached 当组件的 DOM 元素为 "attached" 到 DOM 时调用。可能有子组件,例如 repeated 模板,它们在要渲染的队列中更靠后,最简单的做法是将您的逻辑放在队列的底部:

import {inject, TaskQueue} from 'aurelia-framework';

@inject(TaskQueue)
export class MyComponent {
  constructor(taskQueue) {
    this.taskQueue = taskQueue;
  }

  doSomethingAfterRepeatIsRendered() {
    // your logic...
  }

  attached() {
    this.taskQueue.queueMicroTask({
      call: () => this.doSomethingAfterRepeatIsRendered();
    });
  }
}

有比这更好的方法,但我需要更多地了解您需要对 <li> 元素进行哪些工作才能提供更好的答案。直接使用 TaskQueue 并不常见,通常可以将事物重构为更自然地参与组合生命周期的自定义元素或属性。例如,如果您需要对 <li> 元素执行一些 jQuery 操作,则 "aurelia way" 将使用自定义属性将此逻辑与 view-model 分开:

do-something.js

import {inject, customAttribute} from 'aurelia-framework';
import $ from 'jquery';

@customAttribute('do-something')
@inject(Element)
export class DoSomethingCustomAttribute {
  constructor(element) {
    // "element" will be the DOM element rendered from the
    // template this attribute appears on, in this example an <li> element
    this.element = element;
  }    

  // now we don't need the task queue because attached is called when the 
  // <li> element is attached.
  attached() {
    // this.value is whatever the custom attribute is bound to, in this case
    // its a "thing" from your "things" array.
    $(this.element).doSomething(this.value);
  }
}

用法如下:

app.html

<template>
  <require from="./do-something"></require>

  <ul>
    <li repeat.for="thing of things" do-something.bind="thing"></li>
  </ul>
</template>

想在此处添加另一个用于捕获 DOM 更改的选项,该选项非常简单,不仅适用于 aurelia,而且当您在用户交互中触发一些动态 DOM 更改时可能非常有用, 你可以使用 MutationObserver https://developer.mozilla.org/en/docs/Web/API/MutationObserver

import {DOM} from 'aurelia-pal';
...
let mutationObserver = DOM.createMutationObserver(() => {
   // handle dom changes here
});

//start to observe, note you can set different options
mutationObserver.observe(someDomElement, {childList: true, subtree: true, characterData: true});

当您不再需要观察时,您通常会从 detached()

开始 mutationObserver.disconnect();