Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript TypeError:book.isEqual不是函数_Typescript_Function_Firebase_Typeerror - Fatal编程技术网

Typescript TypeError:book.isEqual不是函数

Typescript 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

在类中定义的方法在其他类中调用时不会被识别为函数

文件: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 { 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));
        //});
      });
  }
}