为什么 Angular 的更改检测会因绑定方法而异?
Why is Angular's change detection inconsistent depending on the binding method?
我在使用服务时遇到了奇怪的变化检测行为。当我将 designElementService.selectedDesignElement 对象引用绑定到 text-element-options 组件的 属性 时,它没有检测到任何对引用的更改 属性.
如果另一个组件,例如,像这样改变它:designElementService.selectedDesignElement=null,text-element-options仍然坚持以前的参考,不会更新 DOM。
但是,如果引用对象的字段或属性发生更改,例如 designElementService.selectedDesignElement.textBlock="Guru meditation detection error."
,则会发生更改检测
作为实验,我使用 @input 将 designElementService.selectedDesignElement 绑定到 text-element -options 并正确检测到更改。是什么导致了这种变化检测行为?服务是否首先 class 参与 Angular 的变更检测?
<text-element-options
*ngIf="
this.designElementService.selectedDesignElement &&
this.designElementService.selectedDesignElement.name === 'text'
"
#textElementOptions
[selectedTextDesignElement]="
this.designElementService.selectedDesignElement
"
></text-element-options>
-
@Component({
selector: "text-element-options",
templateUrl: "./text-element-options.component.html",
styleUrls: ["./text-element-options.component.scss"]
})
export class TextElementOptionsComponent extends DesignElementOptionsComponent {
Alignment = Alignment;
alignment: Alignment = Alignment.left;
decoration: Decoration = <Decoration>{};
// this updates fine
@Input() selectedTextDesignElement: TextDesignElement;
// this one doesn't
// selectedTextDesignElement: TextDesignElement = this.designElementService.selectedDesignElement;
// designElementService
constructor(
public designElementService: DesignElementService,
private resolver: ComponentFactoryResolver
) {
super();
}
}
这实际上与变更检测无关(如果您记录变更检测周期,您会看到它始终如预期的那样 运行),它只是 javascript。
在您的文本元素选项组件中,您已将 selectedTextDesignElement
分配给当前在 designElementService.selectedDesignElement
引用的对象,而不是此服务 属性 持有的当前和未来引用。因此,当您更改服务上的对象引用时,组件中的引用会被破坏,它们仍然指向原始对象。但是改变那个对象显然是有效的,因为它持有相同的引用。这就是为什么你想在共享服务模型中使用 rxjs 主题,而不是像现在这样做。
输入有效,因为这是来自父项的直接更新。
我在使用服务时遇到了奇怪的变化检测行为。当我将 designElementService.selectedDesignElement 对象引用绑定到 text-element-options 组件的 属性 时,它没有检测到任何对引用的更改 属性.
如果另一个组件,例如,像这样改变它:designElementService.selectedDesignElement=null,text-element-options仍然坚持以前的参考,不会更新 DOM。
但是,如果引用对象的字段或属性发生更改,例如 designElementService.selectedDesignElement.textBlock="Guru meditation detection error."
,则会发生更改检测作为实验,我使用 @input 将 designElementService.selectedDesignElement 绑定到 text-element -options 并正确检测到更改。是什么导致了这种变化检测行为?服务是否首先 class 参与 Angular 的变更检测?
<text-element-options
*ngIf="
this.designElementService.selectedDesignElement &&
this.designElementService.selectedDesignElement.name === 'text'
"
#textElementOptions
[selectedTextDesignElement]="
this.designElementService.selectedDesignElement
"
></text-element-options>
-
@Component({
selector: "text-element-options",
templateUrl: "./text-element-options.component.html",
styleUrls: ["./text-element-options.component.scss"]
})
export class TextElementOptionsComponent extends DesignElementOptionsComponent {
Alignment = Alignment;
alignment: Alignment = Alignment.left;
decoration: Decoration = <Decoration>{};
// this updates fine
@Input() selectedTextDesignElement: TextDesignElement;
// this one doesn't
// selectedTextDesignElement: TextDesignElement = this.designElementService.selectedDesignElement;
// designElementService
constructor(
public designElementService: DesignElementService,
private resolver: ComponentFactoryResolver
) {
super();
}
}
这实际上与变更检测无关(如果您记录变更检测周期,您会看到它始终如预期的那样 运行),它只是 javascript。
在您的文本元素选项组件中,您已将 selectedTextDesignElement
分配给当前在 designElementService.selectedDesignElement
引用的对象,而不是此服务 属性 持有的当前和未来引用。因此,当您更改服务上的对象引用时,组件中的引用会被破坏,它们仍然指向原始对象。但是改变那个对象显然是有效的,因为它持有相同的引用。这就是为什么你想在共享服务模型中使用 rxjs 主题,而不是像现在这样做。
输入有效,因为这是来自父项的直接更新。