【问题标题】:Aurelia attached triggers before repeat.forAurelia 在 repeat.for 之前附加了触发器
【发布时间】:2016-01-27 12:35:50
【问题描述】:

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

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

为了说明问题:

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

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

一旦附加被调用(),我希望有一个包含所有 li 元素的渲染 DOM,而不是。一个简单的 dom 转储显示一个空的

如何实现访问这些 li 节点的回调?

【问题讨论】:

    标签: javascript templates aurelia


    【解决方案1】:

    attached 在组件的 DOM 元素“附加”到 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();
        });
      }
    }
    

    还有比这更好的方法,但我需要更多地了解您需要对 &lt;li&gt; 元素进行哪些工作以提供更好的答案。直接使用 TaskQueue 并不常见,通常可以将事物重构为更自然地参与组合生命周期的自定义元素或属性。例如,如果您需要使用 &lt;li&gt; 元素做一些 jQuery 的事情,“aurelia 方式”将是使用自定义属性将此逻辑与您的视图模型分开:

    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>
    

    【讨论】:

    • 非常感谢,实现 taskQueue 似乎正在工作。但是,queueMicroTask 是否可能具有与 queueTask 不同的行为。 (queueTask 似乎不能工作 queueMicroTask)。我正在尝试 li 元素上的一些 jQuery 事件,如果有更好的方法可以做到这一点,我想知道如何。
    • 也感谢您提供更新的答案,这似乎是一种魅力,一件好事,因为在我对工作队列做出初步回应后,它停止了工作。空队列被注入?自定义属性似乎是一个更好(工作)的解决方案。
    【解决方案2】:

    想在这里添加另一个捕获 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();

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多