未定义的数组,尽管它呈现在 dom angular 6
Undefined array although it rendered in dom angular 6
这是我的 Books 组件,其中包含我尝试控制日志的 books 数组。它记录了 undefined
但在使用 *ngFor
.
后它在 DOM 中正确显示
import { Component, OnInit } from '@angular/core';
import { BooksService } from '../shared/books.service';
import { ActivatedRoute, Params } from '@angular/router';
import { Book } from './book.model';
@Component({
selector: 'app-books',
templateUrl: './books.component.html',
styleUrls: ['./books.component.scss']
})
export class BooksComponent implements OnInit {
books: Book[];
filteredBooks: Book[];
id: string;
constructor(
private booksService: BooksService,
private route: ActivatedRoute
) {}
ngOnInit() {
this.booksService.getJson()
.subscribe(response => (
this.books = response.json().books)
);
console.log(this.books) //undefined;
this.route.params.subscribe((params: Params) => {
this.id = params['id'];
});
const filter = this.books.filter(book => book.author === this.id);
console.log(filter);
}
}
Angular 多次渲染您的 books
。 angular 一开始也是 undefined
。
尝试将您的 filter
代码放入您的 subscribe
-Block
你这部分代码有问题:
this.booksService.getJson()
.subscribe(response => (
this.books = response.json().books)
);
console.log(this.books) //undefined;
HTTP 调用是异步的,因此 .subscribe()
中的代码将 运行 在您的 console.log(this.books) //undefined;
之后。
将 console.log
放入 .subscribe()
方法中。
this.booksService.getJson()
.subscribe(response => (
this.books = response.json().books);
console.log(this.books) //undefined;
);
实际上 - 您也在阅读 route.params
中的 id
- 也是一个异步任务。在那种情况下,您应该将 booksService.getJSON()
流与 route.params
流结合起来并执行类似的操作:
Observable.combineLatest(
this.route.params, //1st stream
this.booksService.getJson().map(res => res.json().books) //2nd stream
)
.do((values: any[]) => {
const id = values[0]['id']; //params from 1st stream
const allBooks = values[1]; //already mapped books from 2nd stream
this.filteredBooks = allBooks.filter(book => book.author === id);
}).subscribe();
欢迎来到 Stack Overflow!我在您的代码中看到的问题是您试图在获取 books 数组之前打印它。
您从 BooksService
调用的函数 getJson()
是一个异步调用。意思是,我们不知道在这个函数获取 books 数组之前可能需要多长时间(在某些情况下可能会失败)。
如果你只是想打印图书列表,你可以这样做(注意,我添加了一个错误块来处理错误):
ngOnInit() {
this.booksService.getJson()
.subscribe(
response => { // on success
this.books = response.json().books)
console.log(this.books); // shows your books!
},
error => { // on failure
console.log('Error Occurred:' + JSON.stringify(error));
}
);
// remaining code ...
}
同样在您的模板 (html) 中,您必须在遍历这些书籍之前添加 *ngIf
:
<div *ngIf="books">
<div *ngFor="let book of books">
<div>{{book.name || 'unknown'}}</div>
</div>
</div>
但是,我强烈建议您阅读一些关于 promise chaining、Promise.race 甚至 回调函数 来自这些来源之一。您也可以自由地参考其他地方,但我认为下面的第一个站点 (MDN) 是参考与 javascript 相关的任何内容的好地方:)
这是我的 Books 组件,其中包含我尝试控制日志的 books 数组。它记录了 undefined
但在使用 *ngFor
.
import { Component, OnInit } from '@angular/core';
import { BooksService } from '../shared/books.service';
import { ActivatedRoute, Params } from '@angular/router';
import { Book } from './book.model';
@Component({
selector: 'app-books',
templateUrl: './books.component.html',
styleUrls: ['./books.component.scss']
})
export class BooksComponent implements OnInit {
books: Book[];
filteredBooks: Book[];
id: string;
constructor(
private booksService: BooksService,
private route: ActivatedRoute
) {}
ngOnInit() {
this.booksService.getJson()
.subscribe(response => (
this.books = response.json().books)
);
console.log(this.books) //undefined;
this.route.params.subscribe((params: Params) => {
this.id = params['id'];
});
const filter = this.books.filter(book => book.author === this.id);
console.log(filter);
}
}
Angular 多次渲染您的 books
。 angular 一开始也是 undefined
。
尝试将您的 filter
代码放入您的 subscribe
-Block
你这部分代码有问题:
this.booksService.getJson()
.subscribe(response => (
this.books = response.json().books)
);
console.log(this.books) //undefined;
HTTP 调用是异步的,因此 .subscribe()
中的代码将 运行 在您的 console.log(this.books) //undefined;
之后。
将 console.log
放入 .subscribe()
方法中。
this.booksService.getJson()
.subscribe(response => (
this.books = response.json().books);
console.log(this.books) //undefined;
);
实际上 - 您也在阅读 route.params
中的 id
- 也是一个异步任务。在那种情况下,您应该将 booksService.getJSON()
流与 route.params
流结合起来并执行类似的操作:
Observable.combineLatest(
this.route.params, //1st stream
this.booksService.getJson().map(res => res.json().books) //2nd stream
)
.do((values: any[]) => {
const id = values[0]['id']; //params from 1st stream
const allBooks = values[1]; //already mapped books from 2nd stream
this.filteredBooks = allBooks.filter(book => book.author === id);
}).subscribe();
欢迎来到 Stack Overflow!我在您的代码中看到的问题是您试图在获取 books 数组之前打印它。
您从 BooksService
调用的函数 getJson()
是一个异步调用。意思是,我们不知道在这个函数获取 books 数组之前可能需要多长时间(在某些情况下可能会失败)。
如果你只是想打印图书列表,你可以这样做(注意,我添加了一个错误块来处理错误):
ngOnInit() {
this.booksService.getJson()
.subscribe(
response => { // on success
this.books = response.json().books)
console.log(this.books); // shows your books!
},
error => { // on failure
console.log('Error Occurred:' + JSON.stringify(error));
}
);
// remaining code ...
}
同样在您的模板 (html) 中,您必须在遍历这些书籍之前添加 *ngIf
:
<div *ngIf="books">
<div *ngFor="let book of books">
<div>{{book.name || 'unknown'}}</div>
</div>
</div>
但是,我强烈建议您阅读一些关于 promise chaining、Promise.race 甚至 回调函数 来自这些来源之一。您也可以自由地参考其他地方,但我认为下面的第一个站点 (MDN) 是参考与 javascript 相关的任何内容的好地方:)