我正在尝试使用Angular 6
将一些数据绑定到模板,所以这是ngOnInit
:
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
this.id = +params['id'];
});
let url = this.baseUrl + `/items/${this.id}`;
this.httpClient.get(url).subscribe((data : Array<any>)=> {
this.ItemToEdit = data;
});
}
这是模板:
<div *ngFor="let item of ItemToEdit?.results">
<div class="col-sm-8 float-left">
<mat-form-field> <input matInput
class="form-control" placeholder="Item name"
formControlName="name" id="ItemName" value='{{ item.name }}'>
</mat-form-field>
</div>
</div>
变量ItemToEdit
如下:
{
"results": [
{
"alias": [
"first"
],
"apps": [],
"description": "this is an item",
"id": 1,
"name": "item342"
}
]
}
因此,问题是当我打开模板(通过某个按钮)时,具有ngFor指令的HTML不显示(具有ngFor的div变为空白)。我不知道如何显示数据...变量ItemToEdit
只有一个值(长度= 1),但是由于它有一个名为results
的嵌套数组,因此我通过for循环显示数据。当我尝试在打字稿中执行以下操作时:
this.loadedName = this.ItemToEdit.results[0].name;
我收到一条错误消息,说ItemToEdit.results
未定义
有什么想法吗?
编辑
发现我的代码有效,但只有在刷新页面后...
服务器间歇性地返回这样的响应,而不是预期的结果:
{ "error": "(_mysql_exceptions.OperationalError) (2006, 'MySQL server has gone away') [SQL: 'SELECT .... }
{ "error": "(_mysql_exceptions.ProgrammingError) (2014, \"Commands out of sync; you can't run this command now\") [SQL: 'SELECT ......" }
================编辑2 ==============
我正在获取Mysql异常,因为我正在ngOnInit内进行另一个httpRequest来填充数据库中的选择字段...。 删除该请求后,我的代码可以正常工作。
答案 0 :(得分:0)
尝试使所有进程保持异步
<div *ngFor="let item of (itemToEdit$ | async)">
<div class="col-sm-8 float-left">
<mat-form-field> <input matInput
class="form-control" placeholder="Item name"
formControlName="name" id="ItemName" value='{{ item.name }}'>
</mat-form-field>
</div>
</div>
在您的组件中:
private itemToEdit$: Observable<any>;
....
ngOnInit() {
this.route.params.subscribe(params => {
this.id = +params['id'];
let url = this.baseUrl + `/items/${this.id}`;
this.itemToEdit$ = this.httpClient.get(url).pipe(
map(data => data['results'])
);
});
}
答案 1 :(得分:0)
test: any = [];
ngOnInit() {
this.service.test().subscribe(res => {
this.test = res.results;
});
HTML:
<p *ngFor="let test of this.test">
{{test.name}}
</p>
如果您需要将其绑定到输入字段,只需为其分配:[value]="test?.name"
服务:
test(): Observable<any>{
return this.http.get(url);
}
答案 2 :(得分:0)
您现有的ngOnInit
方法存在问题:
this.id
有机会被设置之前,它会读取this.id
。this.ItemToEdit
发生更改时,它不会更新this.id
。this.id
可能与当前加载的数据的实际ID不符。以下建议的实现方案通过以下方式解决了这些问题:
this.id
中有可用数据时更新this.ItemToEdit
,并且ngOnInit() {
let itemToEditID;
const httpObservable = this.route.params.pipe(
map(params => +params['id']),
tap(newID => itemToEditID = newID),
switchMap(newID => this.httpClient.get(`${this.baseUrl}/items/${newID}`))
);
this.sub = httpObservable.subscribe(data => {
this.id = itemToEditID;
this.ItemToEdit = data;
});
}
将<pre>{{ ItemToEdit | json }}</pre>
放在模板中的某个位置使您可以检查服务器的实际输出,从而可以确定来自服务器的常见错误。
有关这些错误的好消息是它们是由服务器而不是您的代码引起的。坏消息是,您需要确定服务器出了什么问题以及如何解决该问题,但这是另一个问题的话题。
根据您的需要,您可能希望在发生以下情况时在页面上输出服务器错误:
<div *ngIf="ItemToEdit?.error" class="danger">
<h2>An error occurred while trying to retrieve item {{ id }}</h2>
<p>{{ error }}</p>
</div>
<div *ngFor="let item of ItemToEdit?.results">
<!-- ... -->
</div>
答案 3 :(得分:0)
首选解决方案是使用 antoine-clavijo 答案中定义的async
。
或者,如果您的组件(或父组件)是使用ChangeDetectionStrategy.OnPush
定义的,例如:
@Component({
selector: 'app-component',
templateUrl: './config.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
...您可以告诉Angular需要更新组件,如下所示:
constructor(
private ref: ChangeDetectorRef,
private httpClient: HttpClient) {}
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
this.id = +params['id'];
});
const url = this.baseUrl + `/items/${this.id}`;
this.httpClient.get(url).subscribe((data: Array<any>)=> {
this.ItemToEdit = data;
this.ref.detectChanges();
});
}