Angular 从服务加载数据并使用@Input传递给子组件
我使用自定义的Angular 从服务加载数据并使用@Input传递给子组件,angular,Angular,我使用自定义的DataServiceangular服务来获取一些强类型的multi-languagetext数据,这些数据保存在我的phrase字段中。然后我想使用@Input将其传递给子组件 我尝试在ngOnInit和ngOnChangeslifecycle(请参见代码)钩子处加载数据,但在这两种情况下,我的子组件都会收到未定义的 当硬编码短语值时,它会起作用,这告诉我,在我已经向子组件发送了未定义的值之后,数据从服务加载 <child-component [phrase]="this
DataService
angular服务来获取一些强类型的multi-languagetext
数据,这些数据保存在我的phrase
字段中。然后我想使用@Input
将其传递给子组件
我尝试在ngOnInit
和ngOnChanges
lifecycle(请参见代码)钩子处加载数据,但在这两种情况下,我的子组件都会收到未定义的
当硬编码短语
值时,它会起作用,这告诉我,在我已经向子组件发送了未定义的
值之后,数据从服务加载
<child-component [phrase]="this.phrase"></child-component>
相关类型
export class MultiLanguageText {
de: string;
fr: string;
en: string;
}
父模板:
<child-component [phrase]="this.phrase">
</child-component>
/* imports & meta data omitted for readability */
export class ParentComponent implements OnChanges {
phrase: MultiLanguageText;
constructor(private dataService: DataService) {}
ngOnChanges(): void {
this.dataService.getData().then((d) => {
this.phrase = d;
console.log(this.phrase); // logs correct data
});
}
}
<p>{{this.phrase.en}}</p>
/* imports & meta data omitted for readability */
export class ChildComponent {
@Input() phrase: MultiLanguageText;
constructor() {
console.log("phrase equals: ", this.phrase); // logs `undefined`, why?
}
}
/* imports & meta data omitted for readability */
export class ChildComponent {
@Input() phrase: MultiLanguageText;
constructor() {
console.log("phrase equals: ", this.phrase); // logs `undefined`
}
ngOnChanges(): void {
console.log("phrase equals: ", this.phrase); // logs correct data, yay!
}
}
子模板:
<child-component [phrase]="this.phrase">
</child-component>
/* imports & meta data omitted for readability */
export class ParentComponent implements OnChanges {
phrase: MultiLanguageText;
constructor(private dataService: DataService) {}
ngOnChanges(): void {
this.dataService.getData().then((d) => {
this.phrase = d;
console.log(this.phrase); // logs correct data
});
}
}
<p>{{this.phrase.en}}</p>
/* imports & meta data omitted for readability */
export class ChildComponent {
@Input() phrase: MultiLanguageText;
constructor() {
console.log("phrase equals: ", this.phrase); // logs `undefined`, why?
}
}
/* imports & meta data omitted for readability */
export class ChildComponent {
@Input() phrase: MultiLanguageText;
constructor() {
console.log("phrase equals: ", this.phrase); // logs `undefined`
}
ngOnChanges(): void {
console.log("phrase equals: ", this.phrase); // logs correct data, yay!
}
}
更新1:添加了ngOnChanges
HOOK-TO-CHILD组件:
<child-component [phrase]="this.phrase">
</child-component>
/* imports & meta data omitted for readability */
export class ParentComponent implements OnChanges {
phrase: MultiLanguageText;
constructor(private dataService: DataService) {}
ngOnChanges(): void {
this.dataService.getData().then((d) => {
this.phrase = d;
console.log(this.phrase); // logs correct data
});
}
}
<p>{{this.phrase.en}}</p>
/* imports & meta data omitted for readability */
export class ChildComponent {
@Input() phrase: MultiLanguageText;
constructor() {
console.log("phrase equals: ", this.phrase); // logs `undefined`, why?
}
}
/* imports & meta data omitted for readability */
export class ChildComponent {
@Input() phrase: MultiLanguageText;
constructor() {
console.log("phrase equals: ", this.phrase); // logs `undefined`
}
ngOnChanges(): void {
console.log("phrase equals: ", this.phrase); // logs correct data, yay!
}
}
子组件代码:
<child-component [phrase]="this.phrase">
</child-component>
/* imports & meta data omitted for readability */
export class ParentComponent implements OnChanges {
phrase: MultiLanguageText;
constructor(private dataService: DataService) {}
ngOnChanges(): void {
this.dataService.getData().then((d) => {
this.phrase = d;
console.log(this.phrase); // logs correct data
});
}
}
<p>{{this.phrase.en}}</p>
/* imports & meta data omitted for readability */
export class ChildComponent {
@Input() phrase: MultiLanguageText;
constructor() {
console.log("phrase equals: ", this.phrase); // logs `undefined`, why?
}
}
/* imports & meta data omitted for readability */
export class ChildComponent {
@Input() phrase: MultiLanguageText;
constructor() {
console.log("phrase equals: ", this.phrase); // logs `undefined`
}
ngOnChanges(): void {
console.log("phrase equals: ", this.phrase); // logs correct data, yay!
}
}
到目前为止,很好,我现在可以从子组件的控制器访问正确的数据。但是,在模板中,它仍然使用“原始”未定义的值,如何强制模板使用新可用的有效数据
更新2:使用方法获取短语.en
数据
正如@Riron所指出的,phrase
变量是异步设置的,因此在构造子项时,phrase
的值仍然是未定义的。
只要加载短语
数据,就可以在模板中使用它。我解决这个问题的方法是在控制器中使用一种方法:
getPhrase = () => {
return this.phrase === undefined ? "" : this.phrase.en;
}
getPhrase = () => {
return this.phrase === undefined ? "" : this.phrase.en;
}
然后我会从模板中调用它:
<p>{{ getPhrase() }}</p>
<p>{{ getPhrase() }}</p>
{{getPhrase()}
1)使用组件中的参数时,不需要使用此选项
<child-component [phrase]="this.phrase"></child-component>
2) 绑定也是如此
<p>{{phrase}}</p>
{{phrase}
您的短语
变量是异步设置的,因此在构造子项时,短语
的值仍然是未定义的
如果在子组件而不是父组件上实现ngOnChanges
,您应该会在某个点看到值(不是在第一次检查时):
及
正如@Riron所指出的,phrase
变量是异步设置的,因此在构造子项时,phrase
的值仍然是未定义的。
只要加载短语
数据,就可以在模板中使用它。我解决这个问题的方法是在控制器中使用一种方法:
getPhrase = () => {
return this.phrase === undefined ? "" : this.phrase.en;
}
getPhrase = () => {
return this.phrase === undefined ? "" : this.phrase.en;
}
然后我会从模板中调用它:
<p>{{ getPhrase() }}</p>
<p>{{ getPhrase() }}</p>
{{getPhrase()}
您也需要在激励驱动程序表单组件上实现一次更改
,并检查其一次更改
生命周期挂钩中的更改。@echonax感谢您的评论,您是否介意使用一个代码示例来澄清您的观点?我不确定这会是什么样子。它就像你的ParentComponent
一样,只需像Riron一样对它执行ngOnChanges
answer@echonax谢谢,是的,这是有效的,但是,我仍然不明白我现在如何通知模板有效值可用。信息表单哪个模板?虽然你说的是真的,这与所问的问题无关。谢谢,RRIN这有点帮助,但是,模板仍然没有显示有效的价值之后,它是可用的(也请考虑我的更新问题)。你删除了<代码>这个< /代码>在您的模板?您只需要在JS中使用它们code@Riron您应该通过从模板中删除this
来编辑您的答案,以显示您的意思。@Riron@echonax是的,我确实删除了this
。Sry,错误在于我在操作中遗漏了太多内容。在我的子模板中,我评估了{{phrase.en}
,最初,当短语
仍然是未定义
时,它将没有en
属性。我用一个getter来解决它:getPhrase=()=>{返回this.phrase===未定义?“:this.phrase[this.language];}
对不起,我的错。