来回更改路线后可观察到的数据消失了

Posted

技术标签:

【中文标题】来回更改路线后可观察到的数据消失了【英文标题】:Observable data gone after changing routes back and forth 【发布时间】:2019-01-22 13:57:43 【问题描述】:

我一直在开发一个 Angular 应用程序。我有一个events.service,它包含一个方法getEvents(),它从我拥有的Angular Firestore 集合中返回一个Event 类型的Observable。

在我的homepage.component 中,我的getEvents() 方法订阅了事件集合的valueChanges(),它将集合存储到我的数组局部变量Event 中。

现在,它工作得很好,订阅也完美无缺。我从 Firestore 添加、修改或删除的任何文档都会在我的客户端中实时更新。很酷的东西。

问题是当我路由到不同的页面,然后导航回我的主页时,我的局部变量是空的!我不知道为什么。

这是我的代码:

app.module.ts

const appRoutes: Routes = [
     path: "", redirectTo: "/login", pathMatch: "full" ,
     path: "login", component: LoginComponent ,
     path: "signup", component: SignupComponent ,
     path: "home", component: HomepageComponent, canActivate: [AuthGuard] ,
    
      path: "reservepage/:id",
      component: ReservePageComponent
    ,
     path: "scan", component: ScanPageComponent ,
     path: "create", component: CreateEventPageComponent ,
     path: "preview/:id", component: PreviewEventPageComponent 
  ];

event.service.ts

    // Angular imports
    import  Injectable  from "@angular/core";

    // Angular Fire Imports
    import 
      AngularFirestore,
      AngularFirestoreCollection,
      AngularFirestoreDocument,
      fromDocRef
     from "angularfire2/firestore";
    import  AngularFireAuth  from "angularfire2/auth";
    import * as firebase from "firebase";

    // Internal imports
    import  Event  from "./event";
    import  AuthService  from "../auth/auth.service";

    // rxjs imports
    import  Observable, of  from "rxjs";
    import  map  from "rxjs/operators";

    @Injectable(
      providedIn: "root"
    )
    export class EventsService 
      constructor(
        private angularFirestore: AngularFirestore,
        private authService: AuthService,
        private firebaseAuth: AngularFireAuth
      ) 

      collection: AngularFirestoreCollection<
        Event
      > = this.angularFirestore.collection("events");
      collection$: Observable<Event[]> = this.collection.valueChanges();

      document: AngularFirestoreDocument<Event>;
      document$: Observable<Event>;

      id: string;

      add(
        _name: string,
        _description: string,
        _photoURL: string,
        _address?: string,
        _totalTickets?: number,
        _ticketsSold?: number,
        _ticketsAvailable?: number
      ) 
        this.collection
          .add(
            id: "",
            name: _name,
            description: _description,
            photoURL: _photoURL,
            uid: this.firebaseAuth.auth.currentUser.uid,
            address: _address,
            totalTickets: _totalTickets
          )
          .then(docRef => 
            this.collection.doc(docRef.id).update(
              id: docRef.id
            );
            this.setId(docRef.id);
          );
      

      getEvents(): Observable<Event[]> 
        return this.collection$;
      

      getEvent(id: string): Observable<Event> 
        // return a document as a type
        this.document = this.collection.doc(id);
        this.document$ = this.document.valueChanges();
        return this.document$;
      

      setId(id: string) 
        this.id = id;
      

      getId() 
        return this.id;
      
    

homepage.component.ts

// Angular Imports
import  Component, OnInit  from "@angular/core";

// Internal Imports
import  AuthService  from "../../auth/auth.service";
import  NavbarComponent  from "../../components/navbar/navbar.component";
import  EventCardComponent  from "../../components/event-card/event-card.component";
import  Event  from "../../event/event";
import  EventsService  from "../../event/events.service";

// AngularFire imports
import  AngularFirestore  from "angularfire2/firestore";

// rxjs imports
import  Observable  from "rxjs";

// firebase
import * as firebase from "firebase";

@Component(
  selector: "app-homepage",
  templateUrl: "./homepage.component.html",
  styleUrls: ["./homepage.component.css"]
)
export class HomepageComponent implements OnInit 
  constructor(
    private authService: AuthService,
    private eventsService: EventsService,
    private afs: AngularFirestore // public navbar: NavbarComponent
  ) 

  events: Event[] = [];
  myEvents: Event[] = [];

  eventsFilled: boolean;

  getEvents(): void 
    this.eventsService.getEvents().subscribe(events => 
      this.events = events;
      console.log("the length of the events pulled are: " + this.events.length);
    );
  

  ngOnInit() 
    this.getEvents();
    console.log(
      "the length of the events logged from onInit are: " + this.events.length
    );
  

【问题讨论】:

导航返回时是否触发了 ngInit?如果是这样,可能是你的 observable 没有变化,所以你的变量永远不会被重新填充。看看您是否可以在页面加载时从事件服务中显式获取值。 【参考方案1】:

你指的是组件中的局部变量吗?

如果是这样,当您离开某个组件时,该组件将被销毁。它在任何属性(局部变量)中的任何状态都消失了。您不能在路由之间的组件中保留状态。

相反,您可以将该状态存储在服务中。如果您使用根应用程序注入器注册服务,那么即使组件被销毁,该服务也会保留。

【讨论】:

【参考方案2】:

我相信是因为您在组件中有订阅,当您导航组件时可能会被销毁(取决于您如何管理路线),如果是这样,那么每次都会创建订阅

【讨论】:

以上是关于来回更改路线后可观察到的数据消失了的主要内容,如果未能解决你的问题,请参考以下文章

Ember:模型更改时重新渲染路线的模板

Vue:在路线更改时,仅在完成加载后才呈现页面

我在 laravel 5.6 路线中更改了 web.php,但仍然给了我旧路线

Linux性能优化从入门到实战:01 Linux性能优化学习路线

使用可观察的地理坐标集合在 WP7 的 bing 地图上绘制路线

如何使用百度地图查询出行路线