【问题标题】:angular 2 access ng-content within componentangular 2 访问组件内的 ng-content
【发布时间】:2016-08-01 10:12:26
【问题描述】:

如何从组件类本身访问组件的“content”?

我想做这样的事情:

<upper>my text to transform to upper case</upper>

如何获取组件中的内容或上部标记,就像使用 @Input 获取属性一样?

@Component({
    selector: 'upper',
    template: `<ng-content></ng-content>`
})
export class UpperComponent {
    @Input 
    content: String;
}

PS:我知道我可以使用管道进行大写转换,这只是一个例子,我不想创建一个上层组件,只知道如何从组件类中访问组件的内容。

【问题讨论】:

  • 您想要 HTML 字符串还是对特定组件的引用,...?

标签: javascript typescript angular angular2-directives


【解决方案1】:

如果你想获得对被嵌入内容的一个组件的引用,你可以使用:

@Component({
    selector: 'upper',
    template: `<ng-content></ng-content>`
})
export class UpperComponent {
    @ContentChild(SomeComponent) content: SomeComponent;
}

如果您包装&lt;ng-content&gt;,那么您可以访问对嵌入内容的访问,例如

@Component({
    selector: 'upper',
    template: `
  <div #contentWrapper>
    <ng-content></ng-content>
  </div>`
})
export class UpperComponent {
    @ViewChild('contentWrapper') content: ElementRef;

    ngAfterViewInit() {
      console.debug(this.content.nativeElement);
    }
}

【讨论】:

  • 如果我包装它,我应该使用 \@ViewChild 而不是 \@ContentChild 访问它?
【解决方案2】:

为此,您需要利用 @ContentChild 装饰器。

@Component({
  selector: 'upper',
  template: `<ng-content></ng-content>`
})
export class UpperComponent {
  @Input 
  content: String;

  @ContentChild(...)
  element: any;
}

编辑

我对您的问题进行了更多调查,由于您没有根内部 DOM 元素,因此无法在此处使用 @ContentChild

您需要直接利用 DOM。这是一个可行的解决方案:

@Component({
  selector: 'upper',
  template: `<ng-content></ng-content>`
})
export class UpperComponent {
  constructor(private elt:ElementRef, private renderer:Renderer) {
  }

  ngAfterViewInit() {
    var textNode = this.elt.nativeElement.childNodes[0];
    var textInput = textNode.nodeValue;
    this.renderer.setText(textNode, textInput.toUpperCase());
  }
}

查看此 plunkr 了解更多详情:https://plnkr.co/edit/KBxWOnyvLovboGWDGfat?p=preview

【讨论】:

  • 如果被嵌入的内容不是另一个组件怎么办?如果您只想要 ng-content 中的所有嵌入内容怎么办?
【解决方案3】:

https://angular.io/api/core/ContentChildren

class SomeDir implements AfterContentInit {

  @ContentChildren(ChildDirective) contentChildren : QueryList<ChildDirective>;

  ngAfterContentInit() {
    // contentChildren is set
  }
}

请注意,如果您执行 console.log(contentChildren),它仅适用于 ngAfterContentInit 或以后的事件。

【讨论】:

  • 很奇怪,即使使用 forwardref 和后代,我也确实这样做了:是的,检查 AfterContentInit() 并且它仍然作为空列表返回。
【解决方案4】:

早上好,

我一直在对这个主题进行一些研究,因为在我的项目中发生了类似的事情。我发现有两个装饰器可以帮助你解决这个问题:ViewChildren 和 ContentChildren。主要根据我在网络上查到的不同,ViewChildren访问的是组件内部,而ContentChildren访问的是DOM或者组件本身。

要从 ng-content 访问上部元素,您必须更改上部元素,如下所示:

<upper #upper>my text to transform to upper case</upper>

然后简单地访问内部(在具有 ng-content 的组件中):

  @ViewChildren('upper') upper: QueryList<ElementRef>

并访问一般组件(在具有 ng-content 的组件中):

  @ContentChildren('upper') upper: QueryList<ElementRef>

您从哪里获得信息:https://netbasal.com/understanding-viewchildren-contentchildren-and-querylist-in-angular-896b0c689f6e

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    • 2018-08-28
    • 1970-01-01
    相关资源
    最近更新 更多