为什么Angular的变更检测取决于绑定方法不一致?

时间:2019-11-21 23:09:14

标签: angular onchange

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

例如,如果另一个组件对其进行了如下更改: designElementService.selectedDesignElement = null text-element-options 仍然保留先前的引用,并且不会更新DOM。

但是,如果引用对象的字段或属性发生更改,例如 designElementService.selectedDesignElement.textBlock =“大师冥想检测错误”,则会发生更改检测。

作为实验,我使用 @input designElementService.selectedDesignElement 绑定到 text-element-options ,它正确地检测到更改。是什么导致此更改检测行为?服务是一流的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();
  }
}

1 个答案:

答案 0 :(得分:0)

这实际上与更改检测无关(如果您记录更改检测周期,您将看到它始终按预期运行),它只是JavaScript。

在文本元素选项组件中,您已将selectedTextDesignElement分配给当前在designElementService.selectedDesignElement处引用的对象,而不是此服务属性所拥有的当前和将来引用。因此,当您在服务上更改该对象引用时,组件中的引用会损坏,它们仍指向原始对象。但由于该对象具有相同的引用,因此对该对象进行突变显然很有效。这就是为什么您要在共享服务模型中使用rxjs主题,而不是像现在这样做。

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