首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >angular4 ObjectUnsubscribedError

angular4 ObjectUnsubscribedError
EN

Stack Overflow用户
提问于 2017-08-21 21:37:31
回答 1查看 2.4K关注 0票数 4

我正在实现一个angular4客户端应用程序。

我添加了一些服务,这些服务可以从后端发出一些http请求。

然后,它开始抛出以下ObjectUnsubscribedError.

这是一个截图:

经过一些研究,我发现了来自这里的以下警告

我猜由ReactJs rxjs/Subject属性引起的问题。我想,我可能会取消一些错误,但我的取消订阅代码是在ngOnDestroy()方法,这是退出的代码。

因此,我找不到适当的解决办法,也找不到问题的确切原因。

有什么建议或帮助吗?

谢谢

我的代码之一是:

代码语言:javascript
复制
import {Component, Inject, OnDestroy, OnInit} from '@angular/core';
import {Subject} from "rxjs/Subject";

import {APP_CONFIG} from "../../../config/app.config";
import {IAppConfig} from "../../../config/iapp.config";

import {HomelandsService} from "../../../shared/services/homelands.service";
import {SearchService} from "../../../shared/services/search.service";

import {Kelime} from "../../../shared/models/Kelime";
import {City} from "../../../shared/models/homeland/City";
import {County} from "../../../shared/models/homeland/County";
import {Area} from "../../../shared/models/homeland/Area";
import {Neighborhood} from "../../../shared/models/homeland/Neighborhood";
import {HomelandSearchInfo} from "../../../shared/models/HomelandSearchInfo";

@Component({
  selector: 'app-homeland-search-field',
  templateUrl: './homeland-search-field.component.html',
  styleUrls: ['./homeland-search-field.component.css'],
  providers: []
})
export class HomelandSearchFieldComponent implements OnInit, OnDestroy {

  //citiesChanges = new Subject<City[]>();
  countiesChanges = new Subject<County[]>();
  areasChanges = new Subject<Area[]>();
  neighborhoodsChanges = new Subject<Neighborhood[]>();

  cities: City[] = this.appConfig.cities;
  counties: County[];
  areas: Area[];
  neighborhoods: Neighborhood[];

  homelandSearchInfo: HomelandSearchInfo = {
    cityId: null,
    countyId: null,
    areaId: null,
    neighborhoodId: null
  };
  kelimeler: Kelime[];

  constructor(private homelandsService: HomelandsService,
              private searchService: SearchService,
              @Inject(APP_CONFIG) private appConfig: IAppConfig) { }



  ngOnInit() {

    this.countiesChanges = this.homelandsService.countiesChanges;
    this.areasChanges = this.homelandsService.areasChanges;
    this.neighborhoodsChanges = this.homelandsService.neighborhoodsChanges;
    this.countiesChanges.subscribe(
      (counties: County[]) => {
        this.counties = counties;
      }
    );
    this.areasChanges.subscribe(
      (areas: Area[]) => {
        this.areas = areas;
      }
    );
    this.neighborhoodsChanges.subscribe(
      (neighborhoods: Neighborhood[]) => {
        this.neighborhoods = neighborhoods;
      }
    );
    /*this.citiesChanges = this.homelandsService.citiesChanges;
    this.citiesChanges.subscribe(
      (cities: City[]) => {
        this.cities = cities;
        // Loads the cities of Turkey=223
        this.cities = this.homelandsService.getCities().filter((item)=> item.countryId == 223);
      }
    );*/
  }
  ngOnDestroy(){
    this.countiesChanges.unsubscribe();
    this.areasChanges.unsubscribe();
    this.neighborhoodsChanges.unsubscribe();
  }

  // ############################## HOMELAND EVENTs & HELPERs ##############################
  onSelectCity(cityId: number){
    this.homelandSearchInfo.cityId = cityId;
    this.homelandSearchInfo.countyId = null;
    this.homelandSearchInfo.areaId = null;
    this.homelandSearchInfo.neighborhoodId = null;
    //this.counties = this.homelandsService.getCounties().filter((item)=> item.cityId == cityId);
    //this.homelandsService.httpGetCountiesByCityId(cityId);
    this.areas = [];
    this.neighborhoods = [];

  }
  onSelectCounty(countyId: number){
    this.homelandSearchInfo.countyId = countyId;
    this.homelandSearchInfo.areaId = null;
    this.homelandSearchInfo.neighborhoodId = null;
    //this.areas = this.homelandsService.getAreas().filter((item)=> item.countyId == countyId );
    //this.homelandsService.httpGetAreasByCountyId(countyId);
    this.neighborhoods = [];

  }
  onSelectArea(areaId: number){
    this.homelandSearchInfo.areaId = areaId;
    this.homelandSearchInfo.neighborhoodId = null;
    console.log(areaId);
    //this.neighborhoods = this.homelandsService.getNeighborhoods().filter((item)=> item.areaId == areaId );
    //this.homelandsService.httpGetNeighborhoodsByAreaId(areaId);
  }
  onSelectNeighborhood(neighborhoodId: number){
    //this.homelandSearchInfo.neighborhoodId = neighborhoodId;
  }

  onSearch(){
    console.log(this.homelandSearchInfo);

    //1.search servise ilgili bilgileri gönderip sonuçları kelimelerde listelemek.
    this.searchService.searchHomeland(this.homelandSearchInfo);


  }}

====================

代码语言:javascript
复制
import {Inject, Injectable} from '@angular/core';
import {Http} from "@angular/http";
import {Subject} from "rxjs/Subject";

import {APP_CONFIG} from "../../config/app.config";
import {IAppConfig} from "../../config/iapp.config";

import {City} from "../models/homeland/City";
import {County} from "../models/homeland/County";
import {Area} from "../models/homeland/Area";
import {Neighborhood} from "../models/homeland/Neighborhood";
import {Observable} from "rxjs/Observable";
import "rxjs/add/operator/catch";

@Injectable()
export class HomelandsService {

  citiesChanges = new Subject<City[]>();
  countiesChanges = new Subject<County[]>();
  areasChanges = new Subject<Area[]>();
  neighborhoodsChanges = new Subject<Neighborhood[]>();

  cities: City[] = this.appConfig.cities;
  counties: County[] = [];
  areas: Area[] = [];
  neighborhoods: Neighborhood[] = [];

  constructor(private http: Http,
              @Inject(APP_CONFIG) private appConfig: IAppConfig) {
    //this.httpGetCities();
    //this.httpGetCounties();
    //this.httpGetAreas();
    //this.httpGetNeighborhoods();
  }

  getCities(){
    return this.cities.slice();
  }
  getCounties(){
    return this.counties.slice();
  }
  getAreas(){
    return this.areas.slice();
  }
  getNeighborhoods(){
    return this.neighborhoods.slice();
  }


  httpGetCities(){
    let url: string = this.appConfig.backendURL + 'cities/countryId=' + 223;
    this.http.get(url)
      .map(
        (response) => {
          const backendResponse = response.json();
          if(backendResponse.success){
            const cities: City[] = backendResponse.item;
            console.log(cities);
            return cities;
          }else{
            console.error(backendResponse.msg);
            return Observable.throw(backendResponse.msg)
          }
        }
      )
      .catch(
        (error: Response) => {
          console.error(error);
          return Observable.throw(error);
        }
      )
      .subscribe(
        (cities: City[]) => {
          this.cities = cities;
          this.citiesChanges.next(this.cities.slice());
        },
        (error: Error) => {
          console.error(error);
        }
      )
  }

  httpGetCounties(){
    let url: string = this.appConfig.backendURL + 'counties/';
    this.http.get(url)
      .map(
        (response) => {
          const backendResponse = response.json();
          if(backendResponse.success){
            const counties: County[] = backendResponse.item;
            console.log(counties);
            return counties;
          }else{
            console.error(backendResponse.msg);
            return Observable.throw(backendResponse.msg)
          }
        }
      )
      .catch(
        (error: Response) => {
          console.error(error);
          return Observable.throw(error);
        }
      )
      .subscribe(
        (counties: County[]) => {
          this.counties = counties;
          this.countiesChanges.next(this.counties.slice());
        },
        (error: Error) => {
          console.error(error);
        }
      )
  }
  httpGetCountiesByCityId(cityId: number){
    let url: string = this.appConfig.backendURL + 'counties/cityId=' + cityId;
    this.http.get(url)
      .map(
        (response) => {
          const backendResponse = response.json();
          if(backendResponse.success){
            const counties: County[] = backendResponse.item;
            console.log(counties);
            return counties;
          }else{
            console.error(backendResponse.msg);
            return Observable.throw(backendResponse.msg)
          }
        }
      )
      .catch(
        (error: Response) => {
          console.error(error);
          return Observable.throw(error);
        }
      )
      .subscribe(
        (counties: County[]) => {
          this.counties = counties;
          this.countiesChanges.next(this.counties.slice());
        },
        (error: Error) => {
          console.error(error);
        }
      )
  }

  httpGetAreas(){
    let url: string = this.appConfig.backendURL + 'areas/';
    this.http.get(url)
      .map(
        (response) => {
          const backendResponse = response.json();
          if(backendResponse.success){
            const areas: Area[] = backendResponse.item;
            console.log(areas);
            return areas;
          }else{
            console.error(backendResponse.msg);
            return Observable.throw(backendResponse.msg)
          }
        }
      )
      .catch(
        (error: Response) => {
          console.error(error);
          return Observable.throw(error);
        }
      )
      .subscribe(
        (areas: Area[]) => {
          this.areas = areas;
          this.areasChanges.next(this.areas.slice());
        },
        (error: Error) => {
          console.error(error);
        }
      )
  }
  httpGetAreasByCountyId(countyId: number){
    let url: string = this.appConfig.backendURL + 'areas/countyId=' + countyId;
    this.http.get(url)
      .map(
        (response) => {
          const backendResponse = response.json();
          if(backendResponse.success){
            const areas: Area[] = backendResponse.item;
            console.log(areas);
            return areas;
          }else{
            console.error(backendResponse.msg);
            return Observable.throw(backendResponse.msg)
          }
        }
      )
      .catch(
        (error: Response) => {
          console.error(error);
          return Observable.throw(error);
        }
      )
      .subscribe(
        (areas: Area[]) => {
          this.areas = areas;
          this.areasChanges.next(this.areas.slice());
        },
        (error: Error) => {
          console.error(error);
        }
      )
  }

  httpGetNeighborhoods(){
    let url: string = this.appConfig.backendURL + 'neighborhoods/';
    this.http.get(url)
      .map(
        (response) => {
          const backendResponse = response.json();
          if(backendResponse.success){
            const neighborhoods: Neighborhood[] = backendResponse.item;
            console.log(neighborhoods);
            return neighborhoods;
          }else{
            console.error(backendResponse.msg);
            return Observable.throw(backendResponse.msg)
          }
        }
      )
      .catch(
        (error: Response) => {
          console.error(error);
          return Observable.throw(error);
        }
      )
      .subscribe(
        (neighborhoods: Neighborhood[]) => {
          this.neighborhoods = neighborhoods;
          this.neighborhoodsChanges.next(this.neighborhoods.slice());
        },
        (error: Error) => {
          console.error(error);
        }
      )
  }
  httpGetNeighborhoodsByAreaId(areaId: number){
    let url: string = this.appConfig.backendURL + 'neighborhoods/areaId=' + areaId;
    this.http.get(url)
      .map(
        (response) => {
          const backendResponse = response.json();
          if(backendResponse.success){
            const neighborhoods: Neighborhood[] = backendResponse.item;
            console.log(neighborhoods);
            return neighborhoods;
          }else{
            console.error(backendResponse.msg);
            return Observable.throw(backendResponse.msg)
          }
        }
      )
      .catch(
        (error: Response) => {
          console.error(error);
          return Observable.throw(error);
        }
      )
      .subscribe(
        (neighborhoods: Neighborhood[]) => {
          this.neighborhoods = neighborhoods;
          this.neighborhoodsChanges.next(this.neighborhoods.slice());
        },
        (error: Error) => {
          console.error(error);
        }
      )
  }

}

更新:

我已经删除了我的ngOnDestroy()方法中的取消订阅代码,并且错误消失了。但是,主题必须在代码中的某个位置取消订阅。所以,这个问题并没有真正解决。有什么建议吗??

EN

回答 1

Stack Overflow用户

发布于 2018-08-21 21:52:57

不要从主题本身取消订阅,而是创建一个Subscription并取消订阅。取消订阅主题或BehaviorSubject关闭可观察到的内容。试试这个:

代码语言:javascript
复制
import { Subject, Subscription } from 'rxjs';

为订阅创建一个属性,并将其分配给订阅。

代码语言:javascript
复制
countiesChangesSubscription: Subscription;

this.countiesChangesSubscription = this.countiesChanges.subscribe(...)

然后,只需取消订阅,而不是可观察到的本身。

代码语言:javascript
复制
ngOnDestroy() {
  this.countiesChangesSubscription.unsubscribe();
}

对于您不希望关闭的所有订阅,请执行此操作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45805893

复制
相关文章

相似问题

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