Angular, как определить возвращаемое значение для отображения - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь реализовать функцию автозаполнения / опережающего ввода.Но всегда отображается следующая ошибка: TypeError: Невозможно прочитать свойство 'title' из undefined. Как определить возвращаемый результат, чтобы html мог его отобразить?Я не очень знаком с разработкой внешнего интерфейса: (

Спасибо

type-forward.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();
    }
  }

Ответы [ 3 ]

0 голосов
/ 20 сентября 2018

Ваша проблема в том, что вы не передаете правильную переменную.У вас есть предмет, а не фильм.

 <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>
0 голосов
/ 25 сентября 2018

В коде, который я выложил, есть несколько ошибок, в основном из-за несовместимости кодов переднего и заднего плана:

В файле HTML то, что следует после ngFor, должно быть массивомобъектов , которые должны быть определены в файле TS.Но код, который у меня был, просит, чтобы он ссылался на «результаты» («результаты: наблюдаемые»), которые были определены как наблюдаемые , поэтому не могут отображаться правильно;"items: Item []" - это массив объектов, но его значение никогда не устанавливалось должным образом, и на него не ссылались в HTML

Решение: присвойте значения "items" в TS и разрешите ссылаться на HTMLв «элементы» для отображения

Код FYI:

type-forward.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-forward.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)

    })

    }
  }
0 голосов
/ 20 сентября 2018

Я думаю, что это должно быть movie.title

<li>{{movie.title}}</li>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...