3

我正在尝试排除弹出菜单,所以我可以这样写:

<panel-menu>
  <panel-menu-item>Edit input</panel-menu-item>
  <panel-menu-item>Edit mappings</panel-menu-item>
  <panel-menu-item divider-before>Show agent code</panel-menu-item>
</panel-menu>

我有一个panel-menu带有这个 HTML 的组件:

<div class="btn-group" [class.open]="...">
  <button type="button" class="btn btn-default" (click)="..."><i class="ion-gear-b icon-lg"></i></button>
  <ul class="dropdown-menu dropdown-menu-right">
    <ng-content select="panel-menu-item"></ng-content>
  </ul>
</div>

panel-menu-item使用此 HTML:

<li *ngIf="dividerBefore" class="divider"></li>
<li><a><ng-content></ng-content></a></li>

问题是生成的 DOM在和panel-menu-item之间有一个,这会破坏第三方 CSS。ulli

有没有办法只投射所选儿童的内容,而不是儿童本身?

这个答案建议在组件上使用属性li而不是组件,但这会泄漏实现。的用户panel-menu不需要知道菜单项的实现方式是什么元素。

4

1 回答 1

4

要仅投影内容,您应该将内容包装在嵌入式视图中,例如:

面板菜单项.component.ts

@Component({
  selector: 'panel-menu-item',
  template: `
    <ng-template>
      <li *ngIf="dividerBefore" class="divider"></li>
      <li><a><ng-content></ng-content></a></li>
    </ng-template>
  `
})
export class PanelMenuItemComponent {
  @ViewChild(TemplateRef) content: TemplateRef<any>;
}

在前面的代码中,我将模板包装在ng-template标签中,并使用装饰器TemplateRef从中获取实例。@ViewChild

TemplateRef我们可以轻松管理插入模板的位置:

面板菜单.component.ts

@Component({
  selector: 'panel-menu',
  template: `
    <div class="btn-group" >
      <button type="button" class="btn btn-default">Some button</button>
      <ul class="dropdown-menu dropdown-menu-right">
        <ng-container *ngFor="let item of menuItems">
          <ng-container *ngTemplateOutlet="item.content"></ng-container>
        </ng-container>
      </ul>
    </div>
  `
})
export class PanelMenuComponent {
  @ContentChildren(PanelMenuItemComponent) menuItems: QueryList<PanelMenuItemComponent>;

  constructor(private cdRef: ChangeDetectorRef) {}

  ngAfterViewInit() {
    this.cdRef.detectChanges();
  }
}

@ContentChildren用来获取我们的面板菜单项,然后使用内置指令NgTemplateOutlet将内容放入ul.

我们必须通过 using 运行第二个摘要循环,this.cdRef.detectChanges();因为我们会得到错误

ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:'未定义'。当前值:'[object Object]'。

@ViewChild(TemplateRef) content更改检测期间更新其值。

Stackblitz 示例

于 2017-10-12T04:00:19.300 回答