我一直在与Angular4中的某些东西挣扎。请考虑这个Plunker:https://embed.plnkr.co/Sh4LaBtXOfxTzeL996jb/
这是一个简单的应用程序,其中包含3个项目的列表。它显示子组件中允许用户编辑项目的这3个项目。
我想在每次按键(keyup)上更新状态。当我发出新值时,父组件(App)中的数据会更新,这会导致所有项子组件的重新渲染,从而导致输入字段停止聚焦(因为它被替换)。
这意味着用户只能在需要重新聚焦输入之前键入单个字符。
有没有办法阻止重新投放/保持对输入的关注或更好的方式来设置它?
作为对此的临时修复,我现在正在注册localStorage和ngAfterViewInit中已更改的字段我重置焦点......这有效但很难看。我觉得应该有更好的方法吗?
(在Plunker中我设置了一个非常简单的更新,但在我的真实应用程序中我使用了firebase,订阅列表信息,它在发出时将列表作为一个整体提供。当发生这种情况时我将this.list
设置为发出的数据,这会导致重新呈现。)
谢谢!
答案 0 :(得分:7)
您还可以使用ngFor track by功能来防止重新渲染。当您使用track by时,Angular会在指定的属性发生更改时重新创建DOM节点,然后才会重新生成DOM节点,否则会重新使用DOM节点并对其进行更改。
答案 1 :(得分:1)
您可以导入ChangeDetectorRef并根据需要手动禁用/重新启用特定组件的更改。
import { ... other stuff... , ChangeDetectorRef } from '@angular/core'
然后在组件中
constructor( ... other stuff... , private cdr: ChangeDetectorRef) { ... }
ngOnInit() {
this.cdr.checkNoChanges();
}
这可能导致所有类型的视图狡猾,因此您可能只是采取其他评论者的建议并担心防止焦点更改,而不是完全禁用更改检测。您也可以尝试将更改检测设置为OnPush模式,这样可以减少激烈程度。
import { ChangeDetectionStrategy ...otherstuff } '@angular/core'
然后在您需要停止自动向下传播更改的最顶层组件的组件元数据中使用它
@Component({
selector: 'some-name',
changeDetection: ChangeDetectionStrategy.OnPush,
template: ' etc..'
答案 2 :(得分:0)
<强>更新强>
doUpdate(data)
{
//no need to update the whole list, only the item will do the trick!
this.list.items[data.id].name = data.newVal;
}
问题是每次都会生成列表项,因此DOM也会更新,因此失去了重点。
<强> Plunker 强>
旧回答:
这将关注焦点变化:
doUpdate(data)
{
data.preventDefault();
......