comment.component.ts:
import { Component, OnInit } from '@angular/core';
import { Router} from '@angular/router'
import { Comment } from 'comment entity path'
import {CommentService} from 'comment service path'
import { Observable } from 'rxjs/Observable';
@Component({
template: ` <ul><li *ngFor="let comment of comments|async"> {{comment.Name}}</li></ul>`
})
export class CommentComponent implements OnInit {
comments: Observable<comment[]>;
constructor(private router: Router, private commentService: CommentService) {
}
ngOnInit() {
this.comments = this.getComments();
}
getComments() {
return this.commentService.getComments();
}
}
comment.service.ts
import { Injectable } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';
import { Comment } from 'comment path here';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
@Injectable()
export class CommentService {
private commentUrl = 'api path'; // URL to web api
constructor(private http: Http) {
}
getComments(): Observable<Comment[]> {
return this.http.get(this.commentUrl).map(
(response) => {
let data = response.text() ? response.json():[{}];
if (data) {
console.log(data);
return data;
}
return data;
});
}
}
在ngOnInit
方法中,我能够获得评论列表,但问题是列表没有使用HTML上的ngFor
进行绑定。这是因为HTML在响应之前呈现。但是刷新页面数据会自动绑定。我错过了什么吗?
答案 0 :(得分:2)
一种解决方案是仅在您的评论加载后显示您的ul
,然后强制刷新。如下所示:
<ul *ngIf="comments"><li *ngFor="let comment of comments">{{comment.Name}}</li></ul>
因此,一旦加载了comments
,Angular将强制刷新,ul
将被添加到DOM,此时它将拥有绑定{{{}所需的所有数据。每条评论1}}。
答案 1 :(得分:1)
使用异步管道通过observable加载数据。
<li *ngFor="let comment of comments | async">
答案 2 :(得分:1)
您可以使用 ChangeDetectorRef 类强制检测组件及其子组件的更改。 您需要创建类型为 ChangeDetectorRef 的类属性,如下所示:
private cdr: ChangeDetectorRef
在OnInit()中加载数据后,只需调用 detectChanges()方法手动运行更改检测:
this.cdr.detectChanges();
我遇到与angular2相同的问题,从OnInit / AfterViewInit调用API并且视图中没有更新绑定(选择下拉数组未在视图中填充)。 以上方法对我有用,但根本原因对我来说仍然是未知的。
请告诉我这个问题的根本原因,因为我找不到。
答案 3 :(得分:0)
尝试在ul标签中添加ngFor
<ul *ngFor="let comment of comments"><li > {{comment.Name}}</li></ul>`
or
<ul *ngFor="let comment of (comments|async)"> <li> {{comment.Name}}</li></ul>`
也许您还没有粘贴整个代码,我也没有注意到服务组件的注入。
您需要在要使用它的组件中导入和注入服务。 在组件构造函数
中 import {CommentService} from '../path to service'
constructor(private commentService: CommentService)
{
//you can call the getcomments service here itself or in ngOnInit
this.commentService.getComments().subscribe(data =>
{
console.log(data)
}
} //end constructor
希望您已经测试过您的commentService通过console.log
返回数据答案 4 :(得分:0)
试试这个
模板:<ul><li *ngFor="let comment of comments|async"> {{comment.Name}}</li></ul>
comments: Observable<comment[]>;
ngOnInit() {
this.comments = this.getComments();
}
getComments() {
return this.commentService.getComments();
}
我在你的代码中看到了2个问题 1.您调用map而不返回任何值。 2.您尝试在地图中设置值而不是订阅,但是一旦在您的ngOnInit中达到订阅,这些值就是未定义的
答案 5 :(得分:0)
I have found a solution of my issue using Zone and promise.
below is the update code of the "comments.component.ts".
by using zone.run(), I am able to bind data with HTML when
"comments.component" is loaded.
如果数据来自api,这是用HTML绑定数据的正确方法吗?
import { Component, OnInit, NgZone } from '@angular/core'; //NgZone *
import { Router} from '@angular/router'
import { Comment } from 'comment entity path'
import {CommentService} from 'comment service path'
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/toPromise' // *
@Component({
template: `<ul *ngIf="comments && comments.length > 0">
<li *ngFor="let item of comments"> {{item.Name}}</li>
</ul>`
})
export class CommentComponent implements OnInit {
comments: comment[]=[]; // *
constructor(private router: Router, private commentService: CommentService, private zone: NgZone) {
}
ngOnInit() {
this.zone.run(() => {
this.getComments().toPromise().then((data) => {
this.comments= data || [];
});
})
}
getComments() {
return this.commentService.getComments();
}
}
答案 6 :(得分:-1)
以下是我解决问题的方法:
//initialize the variable comment
comments: comment[]; // this is given you have a comment model.
你不应该使用this.classroom
,它应该是:
this.comments = data | [];