【问题标题】:Pass Data using Observable and Subscriber with routes in Angular 2使用 Observable 和 Subscriber 在 Angular 2 中使用路由传递数据
【发布时间】:2017-01-20 13:08:59
【问题描述】:

我有一个 Angular 2 应用程序,我正在使用路由在组件之间导航。为了在兄弟组件之间传递数据,我使用了 Observable 和 Subscription 模式。但是如何通过路由发送数据(我需要传递对象)

app.component.ts

@Component({
 providers: [DataShareService]
})
....

app.component.html

<router-outlet></router-outlet>

数据共享服务

 export class DataShareService {
    // Observable string sources
    private dataSource = new Subject<any>();
    private createdPostSource = new Subject<any>();

    // Observable string streams
    dataSource$ = this.dataSource.asObservable();
    createdPostSource$ = this.createdPostSource.asObservable();
    // Service message commands
    passData(data: any) {
     this.dataSource.next(data);
    }

    passCreatedPostSource(data:IPost[]){
     this.createdPostSource.next(data);
    }

  }

PostListComponent

@Component({
  selector: 'app-post-list',
  templateUrl: './post-list.component.html',
  styleUrls: ['./post-list.component.css']
})
export class PostListComponent implements OnInit {

  private _postUrl: string;
  public posts: IPostList;
  public createPost: string;
  private dataSub: Subscription;

  constructor(private _postService: PostService,
              private _config: ConfigService,
              private  _logger: ErrorLogService,
              private _dataShareService: DataShareService,
              private _router: Router) {
  }


  ngOnInit(): void {
    this._postUrl = this._config.get('postApiRoot');

    this._postService.getPosts(this._postUrl)
      .subscribe(
        result => this.posts = result,
        error => this._logger.logError(error)
      );
    this.dataSub = this._dataShareService.createdPostSource$
      .subscribe(post => {
        this.posts.result.unshift(post);
        console.log(this.posts.result);
      });
  }

  createResponse(post): void {
    this._dataShareService.passData(post);
    console.log("postlist:" + post);
  }

  ngOnDestroy(): void {
    this.dataSub.unsubscribe();
  }
}

html 中的链接

 <a [routerLink]="['/post',post.id]" (click)="createResponse(post)">{{post.title}}</a>

post-detail.component.ts

@Component({
  selector: 'app-post-detail',
  templateUrl: './post-detail.component.html',
  styleUrls: ['./post-detail.component.css']
})
export class PostDetailComponent implements OnInit {

  private _postDetailPath: string;
  private dataSub: Subscription;
  private _post: IPost;

  constructor(private _router: Router,
              private _route: ActivatedRoute,
              private _config: ConfigService,
              private _dataShareService: DataShareService,
              private _logger: ErrorLogService) {

  }

  ngOnInit() {
    this.dataSub = this._dataShareService.dataSource$.subscribe(
      post => {
        this._post = post;
        console.log('post : ' + this._post);
      }, error => {
        console.log('errr0');
        this._logger.logError(error);
      },() => {console.log('post : error' )});

  }

  onBack(): void {
    this._router.navigate(['/posts'])
  }
  ngOnDestroy() {
    this.dataSub.unsubscribe();
  }

}

重定向后无法获取post-detail的ngOnInit()中的数据。

这是如何工作的?如果我不路由它的作品。但是如何使它与路由一起工作?

【问题讨论】:

  • 我面临着类似的问题。我定义了一个通用的RouterService,所有组件都使用它来进行路由。现在我已经集成了 AutGuard,它从 SharedService 传递 boolean observable - 我面临在 RoutinService 中导入 DataSharingService 的问题。不知道是什么问题。

标签: angular angular-routing angular-directive angular-services


【解决方案1】:

服务必须由加载 2 个组件的模块或加载声明组件的两个模块的模块加载,这样您将拥有服务的单例实例并可以在两个组件之间共享数据。

在您的情况下,从组件提供者中删除服务并将其放入 app.module 提供者中。这样您将拥有一个单例并且可以共享数据。

【讨论】:

  • 我做了你让我做的改变,并将 ngOnInit 更改为 this.dataSub = this.dataShareService.dataSource$.subscribe(post => { console.log(post); });进行测试,但没有记录任何内容
  • 它的 .subscribe 似乎永远不会被解雇
  • 我认为您仍然有两个服务实例。您能否向我们提供一个 plunker,以便我们查看整个代码?比如,谁声明了这两个组件?服务在哪里提供,在哪些模块中?
  • 现在它第一次无法正常工作。如果我刷新列表页面并详细单击它不起作用。但是如果我点击返回按钮并单击另一个列表项链接,它就会开始工作,直到我刷新应用程序。
  • 我在使用路由时遇到了完全相同的问题,如果我点击不同的组件最终会触发订阅。你有没有解决过你的问题?
【解决方案2】:

刚刚根据here 的帖子修复了我的问题。你只需替换

new Subject<any>();

new BehaviorSubject(undefined);

然后你可能不得不根据你使用它的方式来处理某个地方的未定义。 我知道这看起来很老套,但它确实有效。

【讨论】:

    猜你喜欢
    • 2016-12-28
    • 1970-01-01
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 2016-09-06
    • 2017-02-28
    • 2017-04-26
    相关资源
    最近更新 更多