我正在构建一个Angular消息组件:
<app-info-card>
my message here
</app-info-card>
这是我的组成部分:
import {AfterViewInit, Component, ContentChild, ElementRef, Input, OnInit} from '@angular/core';
@Component({
selector: 'app-info-card',
templateUrl: './info-card.component.html',
styleUrls: ['./info-card.component.css']
})
export class InfoCardComponent implements OnInit, AfterViewInit {
@ContentChild('app-info-card') messageRef: ElementRef;
message: string;
constructor() {
}
ngOnInit() {
}
ngAfterViewInit() {
this.message = this.messageRef.nativeElement.innerHTML;
console.log(this.messageRef.nativeElement.innerHTML);
}
}
这给了我一个错误,即messageRef未定义。我试图从组件选择器中获取内部文本&#34;我的消息在这里&#34;进入组件的消息字段。有没有办法可以在不添加属性的情况下执行此操作?
答案 0 :(得分:1)
你基本上以一种奇怪的方式使用ContentChild
。您正在引用“app-info-card&#39;本身就是它自己的孩子。来自docs:
您可以使用ContentChild从内容DOM中获取与选择器匹配的第一个元素或指令。如果内容DOM发生更改,并且新子项与选择器匹配,则将更新该属性。
因此,如果您想在组件中放入一些组件/指令并希望以后访问它们,您可以使用ContentChild
或ContentChildren
,方式如下:(来自同一个再次链接)
@Directive({selector: 'pane'})
export class Pane {
@Input() id: string;
}
@Component({
selector: 'tab',
template: `
<div>pane: {{pane?.id}}</div>
`
})
export class Tab {
@ContentChild(Pane) pane: Pane;
}
@Component({
selector: 'example-app',
template: `
<tab>
<pane id="1" *ngIf="shouldShow"></pane>
<pane id="2" *ngIf="!shouldShow"></pane>
</tab>
<button (click)="toggle()">Toggle</button>
`,
})
export class ContentChildComp {
shouldShow = true;
toggle() { this.shouldShow = !this.shouldShow; }
}
话虽如此,您可以将其与类名称一起使用,而不是使用选择器string
。像这样的东西:
@ContentChild(InfoCardComponent) messageRef: InfoCardComponent;
正如我所说,这是一件奇怪的事情,并且会给你InfoCardComponent
组件本身。
无论如何,如果你只想拥有一个包裹元素块的组件,你可以做出两件事:
1-使用@Input
:
如果你只想包装一些文字并以特殊风格展示,你可以简单地拥有一个属性:
@Input() myMessage: string;
并在使用InfoCardComponent
时传递它的值:
<app-info-card [myMessage]="'my message here'"></app-info-card>
然后通过你想要的任何地方绑定来使用它......
2-使用<ng-content></ng-content>
:
如果你想传入组件,不仅仅是文本和包含元素(如<div>
和...),你可以使用内置的<ng-content></ng-content>
指令包含放在初始主机元素中的所有内容(在这种情况下,将是您的<app-info-card></app-info-card>
)。它的工作方式是你只需将它放在你的模板中,如:
<div>
<ng-content></ng-content>
</div>
所有这些方式都有许多细节,并根据您的需要适合某些情况,我刚才提到了使用它们的简短案例。在使用其中任何一个之前,我建议你再次阅读文档。
答案 1 :(得分:1)
我知道这个问题很老,但我找到了这个问题的解决方案,而没有引入额外的(内部/包装的)组件指令。
在需要以字符串形式访问内容的组件模板内部,需要使用ng-template
和ng-content
的包装组合。然后,使用 ViewChild
抓取指向模板的指针。诀窍是模板不会自行呈现,而其内容仍会填充。
需要内容为字符串而不渲染它的组件的模板:
<ng-template #template>
<ng-content></ng-content>
</ng-template>
在同一个组件的 ts 代码中,您将内容作为 TemplateRef
获取,您可以将其呈现在您想要的任何位置:
@ViewChild('template') templateRef!: TemplateRef<unknown>;
最后,您可以完全按照自己的意愿传递内容:
<app-info-card>
my message here
</app-info-card>
答案 2 :(得分:0)
根据您的回答,您需要将该消息传递到您的子组件中。有不同的方法,请看https://angular.io/guide/component-interaction
我建议您在这种情况下使用输入绑定。 使用父模板中的变量
while (guess != theNumber) {
try {
System.out.println("Guess a number between 1 and 100:");
guess = scan.nextInt(); // Reads the number typed on the
// keyboard by the player
count++; // Plus 1 every time a number is entered
System.out.println("You entered " + guess + ".");
if (guess < theNumber) { // If number entered is smaller
System.out.println("The number is bigger" + ", try again!");
System.out.println("Number of tries: " + count);
} else if (guess > theNumber) { // If number entered is
// bigger
System.out.println("The number is smaller" + ", try again!");
System.out.println("Number of tries: " + count);
} else { // If both previous cases are false
System.out.println("Congratulations! You've found the number!");
}
} catch (Exception e) {
System.out.println("Incorrect entering! Please enter a number between 1 and 100.");
scan = new Scanner(System.in);
}
}
您在相应组件中的位置
<app-info-card [message]="message"></app-info-card>
或直接如果它不是动态的(可能不是这种情况)
private message: string = 'my message here';
注意&#39;内部强>
您的子组件中的两种方式都是这样的:
<app-info-card [message]="'my message here'"></app-info-card>
您可能也希望实现OnChanges。如果您还有其他问题,请与我们联系。
答案 3 :(得分:0)
正如@GHB所提到的,我设法使用指令使它起作用。似乎很难直接使用组件的内容,但是通过使用包装指令可以实现。
import { Component, OnInit, ContentChild, AfterContentInit, ElementRef, Directive } from '@angular/core';
@Directive({
selector: 'app-example-code'
})
export class ExampleCodeDirective {}
@Component({
selector: 'app-example-view',
templateUrl: './example-view.component.html',
styleUrls: ['./example-view.component.css']
})
export class ExampleViewComponent implements OnInit, AfterContentInit {
@ContentChild(ExampleCodeDirective, { read: ElementRef })
content: ElementRef;
constructor() { }
ngAfterContentInit() {
if (this.content) {
console.log(this.content.nativeElement.innerText);
}
}
ngOnInit() {
}
}
<app-example-view>
<app-example-code>
some text
</app-example-code>
</app-example-view>
答案 4 :(得分:0)
-Dotel.traces.exporter=jaeger
-Dotel.metrics.exporter=none
-Dotel.exporter.jaeger.endpoint=http://localhost:14250
-Dotel.resource.attributes=service.name=myService
-javaagent:C:/path/to/opentelemetry-javaagent-1.0.1-all.jar