Angular 使用 BehaviorSubject 异步管道扩展组件不工作

Angular extend component with BehaviorSubject async pipe not working

我似乎无法从子组件触发父组件的异步管道来更新视图。 这听起来可能有点令人困惑,但让我尝试通过显示我的代码的简化版本来解释。

如果有一个 class 被另一个 class 扩展。

export class ParentComponent implements OnInit{
    protected subject$: BehaviorSubject<string[]>;

    ngOnInit() {
        this.subject$ = new BehaviorSubject<string[]>([]);
    }
}

模板如下:

<span *ngFor="let niceString of subject$ | async">
    {{niceString}}
</span>

扩展:

export class ChildComponent extends ParentComponent implements OnInit{   
    ngOnInit() {
        super.ngOnInit();

        this.subject$.next(['string1', 'string2']);
    }
}

模板未在浏览器中更新。 如果我在父组件中调用带有 subject$.next 的行,它将按预期更新并在浏览器中显示两个字符串。

所以我尝试通过延迟 3 秒调用 SetTimeOut 来玩弄它,看看它是否以某种方式被快速调用。这并没有解决问题。我还在父函数中添加了 subject$.next ,然后我从子函数中调用了这个函数,这也无法解决它。但是如果我在父 class 中调用相同的新函数,视图会按预期更新。

我还在父级中添加了一个自定义订阅,它像这样收听 subject$:

protected subjectSubscription: Subscription;

this.subjectSubscription = this.subject$.pipe(take(2)).subscribe((justChecking: string[]) => {
    debugger;
});

这将按预期触发,但浏览器中的视图未更新为值 'string1'、'string2'。

我是不是遗漏了什么?

(编辑)添加 StackBlitz:https://stackblitz.com/edit/angular-tt65ig

生命周期方法不会被继承,因此使您的 ChildComponentngOnInit() 方法调用无用。

虽然我更希望您使用服务设计模式,但要以您可以使用的方式做到这一点 super.ngOnInit()

我无法重现所描述的行为。在这里进行一次有效的 stackblitz:https://stackblitz.com/edit/angular-gfxqpe

您是否希望 parent 的模板被 child 使用?那行不通的。您可以引用相同的 html 文件,如

@Component({
  selector: 'app-child',
  templateUrl: '../parent/parent.component.html',
  styleUrls: ['./child.component.css']
})

您正在混合继承和组合:

  • 子组件是一个父组件,因为它扩展了Parent
  • 子组件有一个父组件,因为子组件的模板包含<app-parent>.

因此您正在创建父组件的两个实例:

  • 一个通过在根组件模板中使用 <app-child>。这个父实例是子实例。它的主题发出两个字符串,但它的模板只有 <app-parent> 从不显示这两个字符串。
  • 一个通过在子组件模板中使用 <app-parent>。这个父实例不是子实例。它的模板显示它的主题的内容,但它的主题从不发出任何东西,因为它不是子组件的实例,只有子组件包含发出 2 个字符串的代码。

      parent
       - has subject1
        ^
        -
        |
        |
     extends
        | 
        |                          displays
      child --------------------------------> parent
       - emits from subject1                   - has subject2
                                               - displays content of subject2
    

如何解决?不要那样做。要么使用继承,要么最好使用组合,但不要将两者混用。