【问题标题】:Multiple [ngTemplateOutlet] displays first one only for others also多个 [ngTemplateOutlet] 只为其他人显示第一个
【发布时间】:2018-11-20 03:59:09
【问题描述】:

我正在尝试使用 @ContentChild 获取多个模板引用,但显示第一个。

modal.component.html

<div class="ac-modal">
 <ng-container [ngTemplateOutlet]="modalHeader"></ng-container>
 <ng-container [ngTemplateOutlet]="modalBody"></ng-container>
 <ng-container [ngTemplateOutlet]="modalFooter"></ng-container>
</div>

modal.component.ts

@Component({
  selector: 'ac-modal',
  templateUrl: './modal.component.html',
  styleUrls: ['./modal.component.css']
})
export class ModalComponent implements OnInit, OnDestroy, AfterContentInit {
    @ContentChild(TemplateRef) modalHeader: TemplateRef<void>;
    @ContentChild(TemplateRef) modalBody: TemplateRef<void>;
    @ContentChild(TemplateRef) modalFooter: TemplateRef<void>;

    ngAfterContentInit() {
        console.log("HEADER: ", this.modalHeader);
        console.log("body: ", this.modalBody);
        console.log("footer: ", this.modalFooter);
    }
}

app.component.html

<ac-modal>
    <ac-modal-header *acModalHeader></ac-modal-header>
    <ac-modal-body *acModalBody></ac-modal-body>
    <ac-modal-footer *acModalFooter></ac-modal-footer>
</ac-modal>

modal-footer.directive.ts

@Directive({
  selector: '[acModalFooter]'
})
export class ModalFooterDirective {
    constructor(tempalteRef: TemplateRef<void>,
                modalComponent: ModalComponent) { 
          modalComponent.modalFooter = tempalteRef;
    }
}

modal-header.directive.ts

@Directive({
  selector: '[acModalHeader]'
})
export class ModalFooterDirective {
    constructor(tempalteRef: TemplateRef<void>,
                modalComponent: ModalComponent) { 
          modalComponent.modalHeader = tempalteRef;
    }
}

modal-body.directive.ts

@Directive({
  selector: '[acModalBody]'
})
export class ModalFooterDirective {
    constructor(tempalteRef: TemplateRef<void>,
                modalComponent: ModalComponent) { 
          modalComponent.modalBody = tempalteRef;
    }
}

输出

modal-header works!

modal-header works!

modal-header works!

无论我在modal.component.html 中放在&lt;ac-modal&gt; 组件中的哪个标签都会显示3 次。 3 次,因为我在 modal.component.html 中有 3 个 &lt;ng-container&gt;,但我无法弄清楚为什么会发生这种情况,因为我为每个传递了不同的模板引用。

【问题讨论】:

    标签: angular angular5


    【解决方案1】:

    因为ContentChild 只获得第一个匹配的选择器

    modal.component.ts 更改为

    modalHeader: TemplateRef<void>;
    modalBody: TemplateRef<void>;
    modalFooter: TemplateRef<void>;
    
    @ContentChildren(TemplateRef) templateRefs;
    
    ngAfterContentInit() {
        this.templateRefs.forEach((template: TemplateRef<void>) => {
        if (template === this.modalHeader) {
         //here you can do stuff for ModalHeaderComponent
        }
    
    });
    

    }

    【讨论】:

      【解决方案2】:

      您正在查询 TemplateRef,因此 Angular 将始终为您提供第一个。您想针对您需要的特定指令:

      @ContentChild(ModalHeaderDirective, {read: TemplateRef}) modalHeader: TemplateRef<void>;
      @ContentChild(ModalBodyDirective, {read: TemplateRef}) modalBody: TemplateRef<void>;
      @ContentChild(ModalFooterDirective, {read: TemplateRef}) modalFooter: TemplateRef<void>;
      

      如果你这样做,你甚至不需要在指令中注入ModalComponent@ContentChild 就足以获得TemplateRefs

      【讨论】:

      • 感谢 Eudes,现在说得通了。是否可以使用 renderer2 从 modal.component.ts 向 Header、Body 和 Footer 添加类?因为 ContentChild 将提供 TempletRef ,因为我要求它,但 modalHeader.elementRef.nativeElement 是评论。
      • TemplateRef 是一个“黑匣子”,您将无法从 Modal 组件修改其中的内容。 ac-modal-header 组件必须将一个类本身添加到主机。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-13
      • 2021-03-09
      • 2012-07-15
      • 2018-10-01
      • 2022-08-13
      • 1970-01-01
      • 2017-12-12
      相关资源
      最近更新 更多