【问题标题】:Passing object from one class to another undefined将对象从一个类传递到另一个未定义
【发布时间】:2018-10-30 21:06:47
【问题描述】:

我有一个显示对象列表的组件。当单击此列表中的一个元素时,我想将该对象传递给另一个页面上的另一个组件。

所以基本上是列表组件->服务组件->详情组件->显示点击列表组件详情

列表组件:

setCurrentMovie(movie: IMovie){
    this._currentMovieService.setCurrentMovie(movie);
  }

我用来跟踪当前对象的服务类

  setCurrentMovie(movie: IMovie){
    this.movie = movie;
  }
  getCurrentMovie(): Observable<IMovie>{
    return of(this.movie);
  }

显示当前对象的详细信息组件

getCurrentMovie(){
 console.log(this._currentMovieService.getCurrentMovie().subscribe(value=>this.currentMovie = value)); // logs undefined
}

详情组件html

<div *ngIf="currentMovie">
  {{currentMovie.MovieName}}
</div>

然而这并没有显示任何东西。

【问题讨论】:

  • 您在哪里提供服务。在哪个模块?尝试将服务移至更高级别
  • 您确定您的对象具有MovieName 属性吗? {{ currentMovie | json}} 是否显示任何内容?
  • 你的rxjs是什么版本?
  • 你在哪里调用getCurrentMovie()方法?
  • 在 details 组件的 ngOnInit 中调用

标签: angular typescript observable


【解决方案1】:

ngOnInit 在您的组件初始化时执行,您的getCurrentMovie() 肯定会返回undefined,因为该值尚未设置。稍后,当您设置值时,您的 getCurrentMovie 方法不会被调用,您要么强制调用它,要么使用 Behavior Subject

我建议你选择 RxJS BehaviorSubject

您也可以使用常规的 RxJS Subject 服务,但与subject 相比,它有一些优势。

  1. 订阅时将始终返回当前值 - 无需调用 onnext().
  2. 它有一个 getValue() 函数来提取最后一个值作为原始数据。
  3. 它确保组件始终接收最新数据。
  4. 您可以使用asobservable() 从行为主题中获取可观察的信息 行为主体的方法。
  5. Refer this for more

您的服务

import { Injectable } from '@angular/core';
import {Imovie} from './imovie'
import {Observable,of,BehaviorSubject} from 'rxjs';
@Injectable()
export class ShareDataService {

private Movie= new BehaviorSubject<Imovie>(null);
  currentMovie = this.Movie.asObservable();

  constructor() { }

setCurrentMovie(movie:Imovie)
{
  this.Movie.next(movie);
}
}

组件-1

import { Component, Input } from '@angular/core';
import {ShareDataService} from './share-data.service'
import {Imovie} from './imovie'
@Component({
  selector: 'hello',
  template: `<div *ngIf="currentMovie">
  <h2>{{currentMovie.name}}</h2>
   <h2>{{currentMovie.genre}}</h2>
</div>`,
  styles: [`h1 { font-family: Lato; }`] 
})
export class HelloComponent  {
  public currentMovie:Imovie;
 constructor(public service:ShareDataService)
 {
   this.service.currentMovie.subscribe((value)=>{this.currentMovie=value
     console.log(this.currentMovie);
   });
 }

}

组件-2

import { Component } from '@angular/core';
import {ShareDataService} from './share-data.service'
import {Imovie} from './imovie';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  public movie:Imovie
  constructor(public service:ShareDataService)
  {

  }
setMovie()
{
this.movie={name:'grudge',genre:'horror'};
this.service.setCurrentMovie(this.movie);
}
}

Component-2 HTML

<button (click)="setMovie()" >SetMovie</button>
<hello></hello>

LIVE DEMO

【讨论】:

  • 我在 Component1 中收到错误消息“无法读取未定义的属性 'currentMovie'”
  • 你能提供stackblitz吗?
  • 你提供的stackBlitz遗漏了很多文件,请包括这些文件
猜你喜欢
  • 2016-09-06
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-10
  • 2012-09-04
  • 1970-01-01
相关资源
最近更新 更多