灰烬组件泄漏状态

时间:2017-04-17 21:32:11

标签: javascript ember.js

我是Ember的新手并且有一个泄漏状态问题。我有一个轮播小部件,一次显示一个项目,允许用户点击上一个/下一个查看每个项目。

这是简化的轮播组件:

    await Body.Add(sigPad1 = new SignaturePad { Id = "sigPad1", Enabled = true, LineThickness = 4 }
    .Set(x => x.Style.Border.Color = "red")
    .Set(x => x.Style.Width = 100)
    .Set(x => x.Style.Height = 100));

点击<button {{action "nextItem"}}>Next</button> {{carousel-item item=selectedItem}} 会更改next属性,以便显示下一个项目。

我意识到每次移动到上一个/下一个项目时都不会重新初始化selectedItem组件。 DOM每次都被重用,组件的属性是共享的,因为它只是一个实例,这意味着我可以有泄漏状态。

我看到的替代方案是最初渲染所有项目,因此每个项目都有自己的实例:

carousel-item

并使用CSS隐藏除选定项目之外的所有项目。然而,这种选择感觉就像一个jQuery黑客 - 似乎Ember会有更好的方式。我一次只展示一个项目,所以当我不需要时,我讨厌拥有这么多额外的DOM节点。

处理这种UI的推荐方法是什么,您只需要一次显示一个项目,但又不想在项目之间共享状态?我想我每个项目应该有一个{{#each items as |item|}} {{carousel-item item=item}} {{/each}} 组件的实例,而不是在所有项目中共享一个实例。但是,最初也不一定要实例化每一个carousel-item。我无法想象Ember的方式是自己过多地关注DOM细节(根据类和一些CSS确定显示/隐藏哪一个)。

2 个答案:

答案 0 :(得分:0)

首先,无论你使用的是什么框架或库,jQuery,ember,angular,react,它们只是一包JS / HTML / CSS吧?所以你应该考虑一下,没有魔法!

当然,1个组件只会创建1个实例。如果您刚刚更改了它的属性(演示中的 item ),它只是更改了实例的属性,它的其他属性将保持不变并触发重新渲染。你不能指望更多。您必须手动重置其他属性。

是的,通过{{each}}呈现所有内容看起来很愚蠢,但想一想,你怎么能通过渲染一个DOM创建一个流畅的轮播动画?至少你需要渲染3(当前,上一个和下一个)吗?

由于轮播是一个常见的用户界面,我建议您在自己写作之前检查现有的余烬插件:https://emberobserver.com/?query=carousel

答案 1 :(得分:0)

如果我正确理解了您的问题,Ember.Component类中的willUpdate挂钩应该会帮助您。我这个钩子你可以清理属性,删除DOM对象,或任何东西。每次组件即将重新渲染时,都会调用它。

一个简单的例子是:

{{1}}

这将清除每次重新渲染时的DOM,强制它重绘元素。

你也可以尝试其他钩子,看看哪个事件将满足你的需要。所有这些都非常有用,并且有不同的用途。