无法使用 Observable、Firebase (Angular 6) 为 var 赋值

Posted

技术标签:

【中文标题】无法使用 Observable、Firebase (Angular 6) 为 var 赋值【英文标题】:Can't assign value to var using Observable, Firebase (Angular 6) 【发布时间】:2019-07-11 18:52:50 【问题描述】:

我无法从订阅返回中为任何 var 赋值,我的 observable 名称是 reportess,我试图在我从外部组件声明 observable 的同一服务中将值赋给 var。另一方面,我可以通过记录订阅的返回来打印。

服务:

import  Injectable, Input  from '@angular/core';
//Archivo json
import _reportes from "../archivos json/reportes.json";
import _vacio from "../archivos json/vacio.json";
//Exportador pdf
import * as jsPDF from 'jspdf';
//firebase

import AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument from '@angular/fire/firestore';
import Observable from 'rxjs'
import Subject from 'rxjs'


@Injectable(
 providedIn: 'root'
)
export class ServicesService 
     @Input() reportes
    coleccionReporte: AngularFirestoreCollection<Reporte>;
    reportess: Observable<Reporte[]>;
    reportesMargis;
    reportesDoc: AngularFirestoreDocument<Reporte>;
    ColeccionDeReportes;
    Reporte;

    constructor(public firebase:AngularFirestore)  
    this.reportess = firebase.collection('reporte').valueChanges(); 
    console.log(this.reportes)

组件:

constructor(private reportesServices:ServicesService)  
    ngOnInit() 
    this.reportesServices.reportess.subscribe(data => this.reportesServices.reportes = data ); //dont work  
    this.reportesServices.reportess.subscribe(data => console.log(data) ); //work

【问题讨论】:

你怎么知道第一个例子行不通?因为console.log(this.reportes)ServicesService 的最后一行显示了undefined yes 'console.log(this.reportes)' 行显示未定义 【参考方案1】:

您不能将@Input() 用于service 属性。只需删除它。

它只能用于componentdirective

export class ServicesService 
      reportes;  // removed input decorator
      coleccionReporte: AngularFirestoreCollection<Reporte>;
      reportess: Observable<Reporte[]>;
      reportesMargis;
      reportesDoc: AngularFirestoreDocument<Reporte>;
      ColeccionDeReportes;
      Reporte;



     ..........

【讨论】:

【参考方案2】:

正如@Amit Chigadani 在上面所注意到的,您必须从您的reportes 属性中删除@Input 装饰器。它是公开的,可以从ServicesService 实例访问。所以,代码

this.reportesServices.reportess.subscribe(data => 
    this.reportesServices.reportes = data
);

应该可以。您的console.log(this.reportes) 显示undefined,因为此行在可观察对象解析之前执行。


但是,这样的逻辑看起来有点奇怪,因为服务的东西是在服务之外执行的。我建议稍微重构一下您的服务代码:

import tap from 'rxjs/operators';

this.reportess = firebase.collection('reporte').valueChanges().pipe(
    tap(data => this.reportes = data)
); 

所以存储将在服务内部处理。

【讨论】:

你应该导入它 (import tap from 'rxjs/operators';)。我已经编辑了我的答案。但这只是重构。上面的原始代码也应该可以工作。将您的控制台日志设置为超时,以确保它在可观察对象完成后执行,您将看到setTimeout(() =&gt; console.log(this.reportes), 5000)。这是一个肮脏的把戏,但只是为了向您展示。【参考方案3】:

解决了! 感谢所有的答案。 我用“让”声明了“测试”。在服务中,我声明了一种强制将接收到的数据强制转换为我的对象的方法。

组件:

 constructor(private reportesServices:ServicesService)  

      ngOnInit() 
        let test: any

        this.reportesServices.reportess.subscribe(
          data => 
            test = data;
            this.reportesServices.setReporters(test);
          );         
      

服务:

setReporters(data)
    this.reportes  = [];
    for(let i = 0; i < data.length; i++)
    
      let reporte:Reporte = 
        titulo: data[i].titulo,
        fecha: data[i].fecha,
        ruta: data[i].ruta,
        prioridad: data[i].prioridad,
        funcion: data[i].funcion,
        comentario: data[i].comentario,
        solucionado: data[i].solucionado    
      ;
      this.reportes.push(reporte)
      
  

【讨论】:

以上是关于无法使用 Observable、Firebase (Angular 6) 为 var 赋值的主要内容,如果未能解决你的问题,请参考以下文章

从firebase onchange返回observable

Angular 2 Firebase Observable 承诺不会返回任何东西

观察 Vue Observable 的变化

Firebase Datasnapshot Observable 在通过重定向登录后不会立即更新

Firebase - 使用其他数据填充属性/数组

如何过滤 Observable 数组?