Custom Attribute attached event too early?

时间:2018-02-03 10:18:15

标签: javascript aurelia

The custom component
I've created a custom component for the navigation of my app. It consists of an ul element and all its li elements are dynamically created based on the items in the router's navigation list. This is happening in the attached event of the component. Nothing special is going on here.

The custom attribute
But because I want to have a good looking fancy menu I also created a custom attribute and implemented it into the root ul element of the custom component. In the attached event of the custom attribute I'd like to do some dom manipulations so that my menu looks like a menu created by those cool kids.

The problem
Although the attached event of the custom attribute is fired AFTER the attached event of the custom component, the dynamically created li items are not part of the dom in the attached event of the custom attribute yet.

The question
My assumption was that on attached event the view of the actual component is attached to dom and that all components before are also attached to the dom. And when I am done with the attached event the html that has been dynamically created here is also attached. Am I mistaken?

On a side note
I am aware of using TaskQueue could solve my problem. However, I would like to know if there's a different approach/solution first because I believe that moving things in time could cause a chain of paradoxes leaving you in a maintenance nightmare.

1 个答案:

答案 0 :(得分:0)

请允许我删除您对TaskQueue的误解。

您及时移动导致维护问题的想法肯定适用于使用setTimeout(),因为这会导致实际延迟,并强制执行到下一个事件循环。 queueTask()或多或少是相同的(它在内部使用setTimeout()。)

但是,TaskQueue的queueMicroTask()方法效果非常不同。

当您致电queueMicroTask()时,与queueTask()setTimeout()不同,任务计划在同一事件循环上立即执行 。这是一个非常健壮的机制,具有有保证的执行顺序,在进行任何DOM操作之前,在attached()内使用它通常被认为是一种很好的做法。

事实上,queueMicroTask()由Aurelia在不同地方内部使用(主要在bindingtemplating-resources)。两个值得注意的地方是:

  • 财产和收集观察员使用它来延迟"在所有其他绑定完成内部更新工作之前通知订阅者
  • repeat属性使用它来设置ignoreMutations标志(并在刷新队列后取消设置)以防止在更新其内部集合时无限递归

你通常可以认为有两个"阶段"到bind()和attach()挂钩:一个非排队和一个排队的阶段。排队阶段是组件的工作依赖于整个组件图,首先要完成其他一些(通常是递归的)过程。

queueMicroTask() 不会延迟执行,只需将其推送到调用堆栈的末尾

它的功能相当于将函数作为回调函数传递给调用堆栈的末尾,但是省去了编写找到最后一个调用所需的意大利面条代码并将其连接起来的麻烦。它非常干净。

  

所有li元素都是根据中的项目动态创建的   路由器的导航列表。这发生在附加事件中   组件

请注意,无论何时在attached()期间创建任何内容,您都无法依赖于另一个组件attached()中存在的内容,因为这取决于编译/合成的顺序。这是一个内部问题。对于自定义属性,这是尤其 true。自定义属性(特别是样式库中的属性)在整个地方使用TaskQueue,因为它是唯一可以依赖DOM完成的方式。

在这里使用queueMicroTask()将保证两件事:

  • 当aurelia完全使用"第一遍"附件和渲染
  • 当aurelia完成时,它立即执行 - 甚至没有延迟微秒。

解决这个问题的最好(也许是唯一正确的)方法确实是使用TaskQueue - 我保证:)