代码之家  ›  专栏  ›  技术社区  ›  Robin

行为主体异步管道不工作的角度扩展组件

  •  0
  • Robin  · 技术社区  · 6 年前

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

    如果你有一个被另一个类扩展的类。

    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']);
        }
    }
    

    该模板不会在浏览器中更新。 如果我打电话给主题$。接下来,在父组件中,它将按预期进行更新,并在浏览器中显示这两个字符串。

    所以我试着通过调用SetTimeOut,延迟3秒,看看它是否以某种方式被调用为fast来处理它。这并没有解决问题。我还添加了主题$。下一步是父函数中的一个函数,然后我从子函数调用了它,这也解决不了它。但是,如果我在父类中调用相同的新函数,视图将按预期更新。

    我还在家长中添加了一个自定义订阅,用于收听主题$like so:

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

    将按预期触发,但浏览器中的视图未使用值“string1”、“string2”进行更新。

    我错过什么了吗?

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

    1 回复  |  直到 6 年前
        1
  •  3
  •   JB Nizet    6 年前

    你在混合继承和组合:

    • 子组件 是一个 父组件,因为它扩展了父组件
    • 子组件 有一个 父组件,因为子组件的模板包含 <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
      

    如何修复?不要那样做。要么使用继承,要么更喜欢使用组合,但不要将两者混用。

        2
  •  1
  •   MoxxiManagarm    6 年前

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

    你是否希望孩子使用父母的模板?那不行。您可以引用相同的html文件,如

    @Component({
      selector: 'app-child',
      templateUrl: '../parent/parent.component.html',
      styleUrls: ['./child.component.css']
    })
    
        3
  •  -1
  •   yomateo    6 年前

    生命周期方法不会被继承,因此呈现 ChildComponent 是的 ngOnInit() 方法调用无用。

    尽管我更希望您使用服务设计模式,但要以您可以使用的方式来实现这一点 super.ngOnInit() .

    推荐文章