首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Angular2 2/4不可订阅组件中的可观察到的,这些组件永远不会被销毁

Angular2 2/4不可订阅组件中的可观察到的,这些组件永远不会被销毁
EN

Stack Overflow用户
提问于 2017-11-23 04:09:03
回答 2查看 1.2K关注 0票数 0

我是Angular4的新手。很抱歉我的基本问题和我糟糕的英语。我会尽力描述我的问题。

我现在正在开发一个使用可观察的服务来分享信息的网站。

但我有个问题,这是我的示例文件结构。还有working Plunker

我有“头组件”从“用户组件”接收消息。

标题组件:

代码语言:javascript
运行
复制
import { Component, OnInit, OnDestroy} from '@angular/core';
import { Subscription } from 'rxjs/subscription';
import { SharedService } from "./sharedService";

@Component({
  selector: 'shared-header',
  template: `<div class="my-header">
              <span>This is header </span>
              <span class="right-align">Recieve Data:{{received}}</span>  
            </div>`,
})

export class HeaderComponent implements OnInit, OnDestroy{

  private subscription: Subscription;
  private received = "none";

  constructor(private sharedService : SharedService) {}

  ngOnInit(){
    this.subscription = this.sharedService.shareAction$.subscribe(result => {
      if(result){
        this.received = result;
      } 
    };
  }

  ngOnDestory(){
    this.subscription.unsubscribe();
  }
}

用户组件:

代码语言:javascript
运行
复制
import { Component, OnInit, OnDestroy} from '@angular/core';
import { Subscription } from 'rxjs/subscription';
import { SharedService } from "./sharedService";

@Component({
  selector: 'shared-header',
  template: `<div class="my-header">
              <span>This is header </span>
              <span class="right-align">Recieve Data:{{received}}</span>  
            </div>`,
})

export class HeaderComponent implements OnInit, OnDestroy{

  private subscription: Subscription;
  private received = "none";

  constructor(private sharedService : SharedService) {}

  ngOnInit(){
    this.subscription = this.sharedService.shareAction$.subscribe(result => {
      if(result){
        this.received = result;
      } 
    };
  }

  ngOnDestory(){
    this.subscription.unsubscribe();
  }
}

和"Widget组件“从”“接收消息。

部件组件:

代码语言:javascript
运行
复制
import { Component, OnInit, OnDestroy} from '@angular/core';
import { Subscription } from 'rxjs/subscription';
import { SharedService } from "./sharedService";

@Component({
  selector: 'widget',
  template: `<div>---Widget----</div>
             <div>=={{productName}}==</div>`,
})

export class WidgetComponent implements OnInit, OnDestroy{

  private productName = "none";
  private subscription: Subscription;

  constructor(private sharedService : SharedService) {}

  ngOnInit(){
    this.subscription = this.sharedService.shareAction$.subscribe(result => {
      if(result){
        this.productName = result;
      } 
    };
  }
  ngOnDestory(){
    this.subscription.unsubscribe();
  }
}

产品组成:

代码语言:javascript
运行
复制
import { Component, OnInit, OnDestroy} from '@angular/core';
import { SharedService } from "./sharedService";

@Component({
  template: `<h4>This is ProductPage</h4>
             <widget></widget>`,
})

export class ProductComponent implements OnInit, OnDestroy{

  constructor(private sharedService : SharedService) {}

  ngOnInit(){
    this.sharedService.publishData('NIKE');
  }
}

我创建了一个sharedService来处理可观察的服务。SharedService:

代码语言:javascript
运行
复制
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Subscription } from 'rxjs/subscription';

@Injectable()
export class SharedService {

  private shareAction = new BehaviorSubject<any>(null);
  shareAction$ = this.shareAction.asObservable()
  sharedObject: object = {};

  constructor() {}

  publishData(data) {
    console.log('publish------------------------------');
    this.shareAction.next(data);
  }
}

因此,当单击“用户页”时,标题右侧的信息将显示“用户页”。当单击"Product“时,小部件下面的信息将显示"NIKE”。但在同一时间,标题信息也改变为“耐克”,我不希望它发生。

我知道当组件销毁时我应该取消订阅,但是在这种情况下,头将永远不会被销毁。所以,也许.我应该在“用户组件”破坏时取消订阅,在“用户组件”插入时再次订阅,但是我不知道该如何做,或者这个想法是错误的。

请给我一些指示,任何意见都会有帮助的。非常感谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-23 08:32:09

我认为问题在于,您使用单个shareAction$来做太多事情。为什么不将一个主题作为标题信息,另一个主题用于小部件?

而且,shareAction$太宽泛了:尝试给它一个更具体的名称,比如headerTitle$currentProduct$

代码语言:javascript
运行
复制
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Subscription } from 'rxjs/subscription';

@Injectable()
export class SharedService {

    private headerTitle = new BehaviorSubject<string>(null);
    headerTitle$ = this.headerTitle.asObservable();

    private currentProduct = new BehaviorSubject<any>(null);
    currentProduct$ = this.currentProduct.asObservable();

    constructor() {}

    setHeaderTitle(title:string):void {
        this.headerTitle.next(title);
    }
    setCurrentProduct(product:any):void {
        this.currentProduct.next(product);
    }
}

这样,头组件和Widget组件都不需要知道什么时候订阅/取消订阅:创建时只订阅,销毁时取消订阅。

另外,考虑避免将any作为类型:当您的应用程序足够大时,它将为您节省很多问题,因为如果发生了一些导致错误类型的更改,编译器会告诉您有问题。

您是否需要通过服务在全球共享CurrentProduct?如果您只在组件中使用它,也许通过组件params传递它就足够了。

票数 0
EN

Stack Overflow用户

发布于 2017-11-23 09:11:07

使用内置的角2+机制(\\异步),自动取消订阅。

some.component.ts:

代码语言:javascript
运行
复制
this.heroes = this.heroService.getHeroes();

some.component.html:

代码语言:javascript
运行
复制
<li *ngFor="let hero of heroes | async" (click)="selectedHero=hero">
    <span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47447412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档