2017-11-23 9 views
0

Angular4를 처음 사용합니다. 기본적인 질문과 나의 가난한 영어에 대해 유감스럽게 생각합니다. 내 문제를 설명하기 위해 최선을 다할 것입니다.절대 파괴되지 않는 구성 요소에서 각도 2/4 구독 취소 가능

나는 이제 메시지를 공유하기 위해 관찰 가능한 서비스를 사용하여 웹 사이트를 개발 중입니다.

하지만 문제가 발생했습니다. 여기에 내 example file structure입니다. working Plunker.

"사용자 구성 요소"에서 "헤더 구성 요소"메시지를 받았습니다.

헤더 구성 요소 :

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(); 
    } 
} 

사용자 구성 요소 :

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(); 
    } 
} 

및 "위젯 구성 요소"는 "제품 구성 요소"에서 메시지를 받았습니다.

위젯 구성 요소 :

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(); 
    } 
} 

제품 구성 요소 :

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 : "사용자의 페이지"를 클릭하면

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); 
    } 
} 

그래서, 헤더의 오른쪽에있는 정보는 "사용자의 페이지"를 표시합니다. "제품 페이지"를 클릭하면 위젯 아래의 정보에 "나이키"가 표시됩니다. 그러나 동시에 헤더 정보도 "NIKE"로 바뀌므로 원하지 않습니다.

구성 요소가 삭제 될 때 탈퇴해야한다는 것을 알고 있습니다. 그러나이 경우 헤더는 절대로 파괴되지 않습니다. 그래서 어쩌면 .... 나는 "사용자 구성 요소"가 파괴 될 때 구독을 취소해야하고 "사용자 구성 요소"초기화시 다시 구독해야하지만 어떻게해야할지 모르거나이 아이디어가 좋지 않습니다.

제게 약간의 지시 사항을 알려주십시오. 어떤 의견이라도 도움이 될 것입니다. 고마워요.

+0

왜 당신이 언급 한 구성 요소의 관련 부분을 추가 해달라고? –

+1

의견을 보내 주셔서 감사합니다. – Ryan

답변

0

나는 문제가 너무 많은 것을하기 위해 하나의 shareAction$을 사용하고 있다고 생각한다. 헤더 정보 용 제목과 위젯 용 제목을 모두 만들어보십시오.

또한, shareAction$가 너무 광범위 : 헤더 구성 요소 나 위젯의 구성 요소 중 어느 것도 가입 할 때 알아야 할, headerTitle$currentProduct$

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); 
    } 
} 

처럼, 이런 식으로 좀 더 구체적인 이름을 지정하십시오/탈퇴 : 그들은 만들어 질 때 구독하고 파괴 될 때 구독을 취소합니다.

또한 유형으로 any을 피하십시오. 응용 프로그램이 충분히 큰 경우 문제가 많이 발생합니다. 누락 유형을 유발하는 변경 사항이 있으면 컴파일러에서 잘못된 것이 있음을 알려주기 때문입니다.

서비스를 통해 CurrentProduct을 전세계에 공유해야합니까?제품 구성 요소 - 위젯 구성 요소에서만 사용하는 경우 구성 요소 매개 변수를 전달하면 충분합니다.

+1

고마워, 내 하루를 구해라 !! 네, 전 세계적으로 다른 구성 요소와 공유되는 현재 제품이 필요합니다. 코드를 단순화합니다. 추가 제안 해 주셔서 감사합니다. 정말 도움이됩니다, 매우 감사드립니다! – Ryan

0

각도 2+ 기본 제공 메커니즘 (비동기)을 사용하면 자동으로 수신 거부됩니다.

some.component.ts :

this.heroes = this.heroService.getHeroes(); 

some.component.html :

<li *ngFor="let hero of heroes | async" (click)="selectedHero=hero"> 
    <span class="badge">{{hero.id}}</span> {{hero.name}} 
</li>