如何动态设置已经在使用 *ngFor 的 html 的内容
How to set content of html dynamically which is already using *ngFor
我创建了 html 组件,它使用 *ngFor
动态创建 html 元素。
在 运行 上创建了总共 3 个 <p></p>
标签。 <br>
我在组件文件中提供了动态填充的主题等数据,但标记 属性 是从服务器请求的,我无法在 html 中设置它。
HTML
<div class="home_social">
<p *ngFor="let item of homeItems"> Subject: {{item.subject}}" Marks:{{item.marks}}"</p>
</div>
组件
homeItems = [
{subject: 'Maths', marks: this.home.maths},
{subject: 'Science', marks: this.home.science'},
{subject: 'English', marks: this.home.english}
];
showHomeResource() {
this.appService.getHomeResource().subscribe((data: Home) => this.home = data);
}
ngOnInit(): void {
this.showHomeResource();
}
以这种方式更新标记会出错,因为 this.home.maths 在初始化之前被调用。请求服务器后,Home 对象在 showHomeResource() 中初始化。
我们可以尝试更新组件文件中的标记而不出现此错误,或者我们可以尝试直接访问 html 文件中的 home 对象。
有什么建议吗?
所以,如果我理解错误,我们就有问题了:
homeItems = [
{subject: 'Maths', marks: this.home.maths},//here this.home.math is asynchronous
{subject: 'Science', marks: this.home.science'},
{subject: 'English', marks: this.home.english}
];
在 angular 中,您可以使用 observables 和 rxjs 管理这个异步数据流。显然,这不是让事情正常进行的唯一方法,但对我来说更舒服。所以我假设你有这样的组件
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit{
homeItems = [
{subject: 'Maths', marks: this.home.maths},
{subject: 'Science', marks: this.home.science},
{subject: 'English', marks: this.home.english}
];
home: any;
constructor(
) {
}
ngOnInit() {
this.appService.getHomeResource().subscribe((data: Home) => this.home = data);
}
showHomeResource() {
this.appService.getHomeResource().subscribe((data: Home) => this.home =
data);
}
}
你的问题是当你初始化 homeItems 时,你试图访问 home,但是 home 是未定义的 moment.a 使用 rxjs 做到这一点的方法是:
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit{
homeItems$ = new Observable(); //we can transform homeItems$ in an observable, the $ is a convention
home: any;
constructor(
) {
}
ngOnInit() {
this.homeItems$ = this.appService.getHomeResource().pipe(
map((data: Home) => { //tha map method is like the array.map of js, but are you mapping your data!
this.home = data
return [
{subject: 'Maths', marks: this.home.maths }, //here we can assign to the homeItems$ marks our value. the trick is that in this moment we are not rendering the view, check the html file to understand
{subject: 'Science', marks: this.home.science},
{subject: 'English', marks: this.home.english}
];
})
}
}
如果您看到我们没有在控制器中订阅。因为我们可以在 html 文件中以清晰的方式进行。
<ng-container *ngIf="homeItems$ | async; let homeItems"> <!-- here we subscribing the observable and we assign the value in homeItems -->
<div class="home_social">
<p *ngFor="let item of homeItems"> Subject: {{item.subject}}" Marks:{{item.marks}}"</p> <!-- here we are sure that we have data -->
</div>
</ng-container>
我创建了 html 组件,它使用 *ngFor
动态创建 html 元素。
在 运行 上创建了总共 3 个 <p></p>
标签。 <br>
我在组件文件中提供了动态填充的主题等数据,但标记 属性 是从服务器请求的,我无法在 html 中设置它。
HTML
<div class="home_social">
<p *ngFor="let item of homeItems"> Subject: {{item.subject}}" Marks:{{item.marks}}"</p>
</div>
组件
homeItems = [
{subject: 'Maths', marks: this.home.maths},
{subject: 'Science', marks: this.home.science'},
{subject: 'English', marks: this.home.english}
];
showHomeResource() {
this.appService.getHomeResource().subscribe((data: Home) => this.home = data);
}
ngOnInit(): void {
this.showHomeResource();
}
以这种方式更新标记会出错,因为 this.home.maths 在初始化之前被调用。请求服务器后,Home 对象在 showHomeResource() 中初始化。
我们可以尝试更新组件文件中的标记而不出现此错误,或者我们可以尝试直接访问 html 文件中的 home 对象。
有什么建议吗?
所以,如果我理解错误,我们就有问题了:
homeItems = [
{subject: 'Maths', marks: this.home.maths},//here this.home.math is asynchronous
{subject: 'Science', marks: this.home.science'},
{subject: 'English', marks: this.home.english}
];
在 angular 中,您可以使用 observables 和 rxjs 管理这个异步数据流。显然,这不是让事情正常进行的唯一方法,但对我来说更舒服。所以我假设你有这样的组件
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit{
homeItems = [
{subject: 'Maths', marks: this.home.maths},
{subject: 'Science', marks: this.home.science},
{subject: 'English', marks: this.home.english}
];
home: any;
constructor(
) {
}
ngOnInit() {
this.appService.getHomeResource().subscribe((data: Home) => this.home = data);
}
showHomeResource() {
this.appService.getHomeResource().subscribe((data: Home) => this.home =
data);
}
}
你的问题是当你初始化 homeItems 时,你试图访问 home,但是 home 是未定义的 moment.a 使用 rxjs 做到这一点的方法是:
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit{
homeItems$ = new Observable(); //we can transform homeItems$ in an observable, the $ is a convention
home: any;
constructor(
) {
}
ngOnInit() {
this.homeItems$ = this.appService.getHomeResource().pipe(
map((data: Home) => { //tha map method is like the array.map of js, but are you mapping your data!
this.home = data
return [
{subject: 'Maths', marks: this.home.maths }, //here we can assign to the homeItems$ marks our value. the trick is that in this moment we are not rendering the view, check the html file to understand
{subject: 'Science', marks: this.home.science},
{subject: 'English', marks: this.home.english}
];
})
}
}
如果您看到我们没有在控制器中订阅。因为我们可以在 html 文件中以清晰的方式进行。
<ng-container *ngIf="homeItems$ | async; let homeItems"> <!-- here we subscribing the observable and we assign the value in homeItems -->
<div class="home_social">
<p *ngFor="let item of homeItems"> Subject: {{item.subject}}" Marks:{{item.marks}}"</p> <!-- here we are sure that we have data -->
</div>
</ng-container>