为什么 Angular 的更改检测会因绑定方法而异?

Why is Angular's change detection inconsistent depending on the binding method?

我在使用服务时遇到了奇怪的变化检测行为。当我将 designElementService.selectedDesignElement 对象引用绑定到 text-element-options 组件的 属性 时,它没有检测到任何对引用的更改 属性.

如果另一个组件,例如,像这样改变它:designElementService.selectedDesignElement=nulltext-element-options仍然坚持以前的参考,不会更新 DOM。

但是,如果引用对象的字段或属性发生更改,例如 designElementService.selectedDesignElement.textBlock="Guru meditation detection error."

,则会发生更改检测

作为实验,我使用 @inputdesignElementService.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 主题,而不是像现在这样做。

输入有效,因为这是来自父项的直接更新。