【问题标题】:Can't assign value to var using Observable, Firebase (Angular 6)无法使用 Observable、Firebase (Angular 6) 为 var 赋值
【发布时间】: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)' 行显示未定义

标签: angular typescript firebase google-cloud-firestore observable


【解决方案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)
        }  
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-04
      • 1970-01-01
      • 1970-01-01
      • 2018-11-24
      • 1970-01-01
      相关资源
      最近更新 更多