Typescript TypeError:book.isEqual不是函数
在类中定义的方法在其他类中调用时不会被识别为函数 文件:models/book.model.tsTypescript TypeError:book.isEqual不是函数,typescript,function,firebase,typeerror,Typescript,Function,Firebase,Typeerror,在类中定义的方法在其他类中调用时不会被识别为函数 文件:models/book.model.ts export class Book { constructor(public title: string, public author: string) { } isEqual (other: Book ): boolean { return (this === other); } } 文件:services/books.service.ts import
export class Book {
constructor(public title: string, public author: string) {
}
isEqual (other: Book ): boolean {
return (this === other);
}
}
文件:services/books.service.ts
import { Book } from '../models/book.model';
import { Subject } from 'rxjs/Subject';
import * as firebase from 'firebase';
import DataSnapshot = firebase.database.DataSnapshot;
export class BooksService {
books = [new Book ('', '')]
booksSubject = new Subject<Book[]>();
constructor() {
this.getBooks();
}
emitBooks() {
this.booksSubject.next(this.books);
}
getBooks() {
firebase.database().ref('/books')
.on('value',
(data: DataSnapshot) =>
{
this.books = data.val() ? data.val() : [];
this.emitBooks(); /
}
);
}
indexOfBook (book: Book) {
const bookIndex = this.books.findIndex(
(a_book) => {return book.isEqual (a_book)}
);
return bookIndex;
}
从“../models/Book.model”导入{Book};
从'rxjs/Subject'导入{Subject};
从“firebase”导入*作为firebase;
导入DataSnapshot=firebase.database.DataSnapshot;
出口类图书服务{
书籍=[新书('','')]
booksubject=新主题();
构造函数(){
这个。getBooks();
}
电子图书(){
this.booksSubject.next(this.books);
}
getBooks(){
firebase.database().ref(“/books”)
.on('值',
(数据:DataSnapshot)=>
{
this.books=data.val()?data.val():[];
这本书()/
}
);
}
索引书(书:书){
const bookIndex=this.books.findIndex(
(一本书)=>{return book.isEqual(一本书)}
);
返回图书索引;
}
我想把“book.isEqual”方法称为“book类图书服务”。
book.isEqual没有被识别为函数,为什么?Firebase返回一些数据,但它只是一个对象:您需要使用
new book()
从该数据中创建一个book
实例
因为我不知道Firebase在
val()
中返回了什么,所以这只是一个示例,假设数据包含[author,title]
元组数组,但您知道了。也许它实际上是新书(Book.author,Book.title)
…创建大量当前代码所需的新类实例非常费劲,而且可能没有必要
这里有一个替代方案,它使用接口
s(根本不发送到JavaScript)和一个非常简化的索引搜索
export interface Book {
title: string;
author: string;
}
然后在服务中,一个小小的改变,将您的报税表转换为图书[]
:
this.books = data.val() ? (data.val() as Book[]) : [];
然后可以使用helper函数并完全放弃类。以前,它混合使用了箭头函数和大括号返回语句,并且不需要isEqual helper,因为整个过程可以简化为:
indexOfBook = (needle: Book) => this.books.findIndex(
book => book.author == needle.author && book.title == needle.title
);
我已经创建了这个stackblitz项目,它运行良好,您可以检查它
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import * as firebase from 'firebase/app';
// These imports load individual services into the firebase namespace.
import 'firebase/auth';
import 'firebase/database';
import DataSnapshot = firebase.database.DataSnapshot;
const config = {
apiKey: "AIzaSyAh-EgWckq1oexuxQ0vVSbKE6jIOGDPcu4",
authDomain: "yallswall.firebaseapp.com",
databaseURL: "https://yallswall.firebaseio.com",
projectId: "yallswall",
storageBucket: "yallswall.appspot.com",
messagingSenderId: "109317481518",
appId: "1:109317481518:web:14342c0b3d54017f"
};
class Book {
constructor(public title: string, public author: string) {
}
isEqual (other: Book): boolean {
return (this === other);
}
}
@Component({
selector: 'my-app',
template: `
<ul>
<li class="text" *ngFor="let book of books">
{{book.title}} : {{book.author}}, {{book.isEqual(book)}}
</li>
</ul>
`
})
export class AppComponent {
books: Book[] = [];
constructor() {
firebase.initializeApp(config);
this.getBooks();
}
getBooks() {
firebase.database().ref('books')
.on('value', (data: DataSnapshot) => {
this.books = data && data.val().map(bookLike => new Book(bookLike.title, bookLike.author)) || [];
//the code below works too
//this.books = [];
//data && data.forEach(e => {
// const bookLike = e.val();
// this.books.push(new Book(bookLike.title, bookLike.author));
//});
});
}
}
从'@angular/core'导入{Component};
从“rxjs”导入{Observable};
从“rxjs/operators”导入{map};
从“firebase/app”导入*作为firebase;
//这些导入将单个服务加载到firebase命名空间中。
导入“firebase/auth”;
导入“firebase/数据库”;
导入DataSnapshot=firebase.database.DataSnapshot;
常量配置={
apiKey:“AIzaSyAh-EgWckq1oexuxQ0vVSbKE6jIOGDPcu4”,
authDomain:“yallswall.firebaseapp.com”,
数据库URL:“https://yallswall.firebaseio.com",
投射物:“耶尔斯沃尔”,
storageBucket:“yallswall.appspot.com”,
messagingSenderId:“109317481518”,
appId:“1:109317481518:web:14342c0b3d54017f”
};
课堂用书{
构造函数(公共标题:string,公共作者:string){
}
isEqual(其他:书籍):布尔值{
返回(此==其他);
}
}
@组成部分({
选择器:“我的应用程序”,
模板:`
-
{{book.title}}:{{book.author},{{{book.isEqual(book)}
`
})
导出类AppComponent{
书籍:书籍[]=[];
构造函数(){
firebase.initializeApp(配置);
这个。getBooks();
}
getBooks(){
firebase.database().ref('books')
.on('值',(数据:DataSnapshot)=>{
this.books=data&&data.val();
//下面的代码也适用
//本书=[];
//data&&data.forEach(e=>{
//常量bookLike=e.val();
//this.books.push(新书(bookLike.title,bookLike.author));
//});
});
}
}
如果是一个TypeError,则表明您在运行时遇到了错误,与TypeScript键入无关。是否正确?如果是,这也表明book
实际上不是book
类的实例。您是否确保它实际上是一个book
?是否可以添加错误日志?我不知道我不熟悉firebase,但我很确定,如果您从数据库检索图书,它们不会自动使用isEqual
方法。我怀疑这就是您遇到问题的原因。我也不熟悉firebase。我怀疑问题来自于此。可能存在:this.books=data.val()?data.val():[];如何告诉firebase books是一个Book数组?很抱歉,我不明白map操作符在做什么。构造函数中books数组的console.log给出了以下输出:数组books是(5)[…]0:对象{作者:“维克多·雨果”,简介:,标题:“悲惨世界”}1:对象{作者:“约翰·勒·卡雷”,简介:“扎兹尔特”,标题:“间谍的遗产”}等等…
我不知道如何和在哪里进行此转换。(我在角度上是非常新的)我尝试了以下方法:this.books=data.val()?data.val().map(book=>newbook(book.title,book.author)):[];
编译,但给出了与我相同的错误:constbookindex=this.books.findIndex((a_book)=>{consttheu book=newbook=(a_book.title,a_book.author);返回_book.isEqual(book)}
以铸造_book并使用isEqual方法。这远远不够优雅。有人能给我一个更好的答案吗?(还有,如何格式化此文本?)@EmileAchadde我保留这个答案是出于历史目的,但添加了第二个答案,该答案重写了带有接口的代码,简化了搜索。感谢您提供了这个优雅的解决方案。@EmileAchadde这个问题是关于让isEqual工作还是让indexOfBook工作?问题是:当在cl一书中定义isEqual时,如何让isEqual工作屁股。
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import * as firebase from 'firebase/app';
// These imports load individual services into the firebase namespace.
import 'firebase/auth';
import 'firebase/database';
import DataSnapshot = firebase.database.DataSnapshot;
const config = {
apiKey: "AIzaSyAh-EgWckq1oexuxQ0vVSbKE6jIOGDPcu4",
authDomain: "yallswall.firebaseapp.com",
databaseURL: "https://yallswall.firebaseio.com",
projectId: "yallswall",
storageBucket: "yallswall.appspot.com",
messagingSenderId: "109317481518",
appId: "1:109317481518:web:14342c0b3d54017f"
};
class Book {
constructor(public title: string, public author: string) {
}
isEqual (other: Book): boolean {
return (this === other);
}
}
@Component({
selector: 'my-app',
template: `
<ul>
<li class="text" *ngFor="let book of books">
{{book.title}} : {{book.author}}, {{book.isEqual(book)}}
</li>
</ul>
`
})
export class AppComponent {
books: Book[] = [];
constructor() {
firebase.initializeApp(config);
this.getBooks();
}
getBooks() {
firebase.database().ref('books')
.on('value', (data: DataSnapshot) => {
this.books = data && data.val().map(bookLike => new Book(bookLike.title, bookLike.author)) || [];
//the code below works too
//this.books = [];
//data && data.forEach(e => {
// const bookLike = e.val();
// this.books.push(new Book(bookLike.title, bookLike.author));
//});
});
}
}