我正在尝试实现自动完成/预输入功能。但是始终会显示以下错误: TypeError:无法读取未定义的属性'title'。我如何定义返回的结果,以便html可以显示它?我对前端开发不是很熟悉:(
谢谢
type-ahead.component.html
<h1>Start Typing...</h1>
<input (keyup)="onkeyup($event)" placeholder="search movies...">
<ul *ngFor="let movie of results | async" class="card">
<li>{{item.title}}</li>
</ul>
type-ahead.component.ts
import { Component, OnInit } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { switchMap, filter } from 'rxjs/operators';
import { Item } from '../../models/Item'
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
@Component({
selector: 'app-type-ahead',
templateUrl: './type-ahead.component.html',
styleUrls: ['./type-ahead.component.css']
})
export class TypeAheadComponent implements OnInit {
items: Item[];
results: Observable<Item[]> ;// this will be an array of item documents
offset : BehaviorSubject<string|null> = new BehaviorSubject("");
//offset = new Subject <string>();// this will be the term the user search for
constructor(private afs: AngularFirestore) { }
//event handler, whenever the key is pressed we call the event, which is to check the next one
onkeyup(e){
console.log("e target value is like",e.target.value)
this.offset.next(e.target.value.toLowerCase())
console.log("let see if the offest is successfully captured",this.offset)
}
//Observe that offset value, filter out any null value, which will throw firestore error.
//Reactive search query
search() {
return this.offset.pipe(
filter(val => !!val), // filter empty strings
switchMap(offset => {
return this.afs.collection('items', ref =>
ref.orderBy(`searchableIndex.${offset}`).limit(5)
)
.valueChanges()
})
)
}
ngOnInit() {
this.results = this.search();
}
}
答案 0 :(得分:2)
我认为应该是movie.title
<li>{{movie.title}}</li>
答案 1 :(得分:1)
您的问题是您没有传递正确的变量。您有项目,而不是电影。
<ul *ngFor="let movie of results | async" class="card">
<li>{{movie.title}}</li>
</ul>
或者您可以执行以下操作
<ul *ngFor="(let movie of results | async) as item" class="card">
<li>{{item.title}}</li>
</ul>
答案 2 :(得分:0)
我发布的代码中存在多个错误,主要是由于前端和后端代码不兼容:
在HTML文件中,ngFor之后的内容应为对象数组,该对象应在TS文件中定义。但是我得到的代码要求它引用定义为 observable 的“结果”(“ results:Observable”),因此无法正确显示; “ items:Item []”是一个对象数组,但从未正确设置其值,因此在HTML中未引用
解决方案:在TS中为“项目”分配值,然后让HTML引用“项目”进行显示
代码供参考:
type-ahead.component.html
<h1>Start Typing...</h1>
<input (keyup)="onkeyup($event)" placeholder="search movies...">
<ul *ngFor="let item of items" class="card">
<li>{{item.title}}</li>
</ul>
type-ahead.component.ts
import { Component, OnInit } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { switchMap, filter } from 'rxjs/operators';
import { Item } from '../../models/Item'
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
@Component({
selector: 'app-type-ahead',
templateUrl: './type-ahead.component.html',
styleUrls: ['./type-ahead.component.css']
})
export class TypeAheadComponent implements OnInit {
items: Item[];
results: Observable<Item[]> ;// this will be an array of item documents
offset : BehaviorSubject<string|null> = new BehaviorSubject("");
//offset = new Subject <string>();// this will be the term the user search for
constructor(private afs: AngularFirestore) { }
//event handler, whenever the key is pressed we call the even, which is to check the next one
onkeyup(e){
console.log("e target value is like",e.target.value)
this.offset.next(e.target.value.toLowerCase())
console.log("let see if the offest is successfully captured",this.offset)
}
//Observe that offset value, filter out any null value, which will throw firestore error.
//Reactive search query
search() {
return this.offset.pipe(
filter(val => !!val), // filter empty strings
switchMap(offset => {
return this.afs.collection('items', ref =>
ref.orderBy(`searchableIndex.${offset}`).limit(5)
)
.valueChanges()
})
)
}
ngOnInit() {
this.results= this.search();
this.results.subscribe(itemsFrmDB =>{
this.items=itemsFrmDB;
console.log("this.item: ",this.items)
})
}
}