导航到其他页面不起作用时清除订阅

Clearing subscription when navigating to other page not working

我正在开发一个简单的搜索屏幕 来学习 angular 我觉得非常混乱的订阅。 在我的主页页面中,我创建了两个组件。一个过滤器组件和第二个搜索结果组件。

这是我的过滤服务

export class FilterService {
    private filtersubject = new Subject<Filter>();
    public currentfilters: Observable<Filter>;

    constructor() {
        this.filtersubject = new BehaviorSubject<Filter>(Filter.getInstance());
        this.currentfilters = this.filtersubject.asObservable();
    }

    getFilters(): Observable<Filter> {
       return this.filtersubject.asObservable();
    }

    sendFilterMessage() {
      this.filtersubject.next(Filter.getInstance());
    }

    clearFilterMesasage() {
       this.filtersubject.next(new Filter());
    }
}

这是我的搜索结果服务

export class SearchresultsService {
  public searchresult!: Observable<ResultData[]>;
  private searchresultsubject = new Subject<ResultData[]>();
  private f: Filter = Filter.getInstance();
  subscription: Subscription;
  

  constructor( private httpClient: HttpClient, private filterservice: FilterService ) {
    this.subscription = this.filterservice.currentfilters.subscribe(
    (filter: Filter) => {
      this.f = filter;
      this.searchData();
      this.searchresult = this.searchresultsubject.asObservable();
    });
  }  

  public searchData(): void {
    const url = `${environment.ssoUrl}api/SearchrResult`;
    this.httpClient.get<ResultData[]>(url, { params, responseType : 'json'}).
    subscribe((response: ResultData[]) => {
      this.searchresultsubject.next(response);
    });
  }
 }

在搜索结果中,每条导航到详细信息页面的记录都有一个 link。在那里你做了一些 CRUD 操作,然后在提交时导航回到主页。问题在于,在 CRUD 操作和导航回搜索屏幕之后,订阅从未被清除并保留了之前的搜索选项。在搜索组件中我有

resetFilterData(formid: number){    
  this.filterservice.clearFilterMesasage();
  this.router.navigate(["details", id]);
}

也在homecomponents.ts我有

export class HomeComponent implements OnInit, OnDestroy {  
    subscription: any;
    constructor(
        private router: Router,
        public filterSer: FilterService ) {    
        this.subscription = this.filterSer.currentfilters.subscribe();
    }
    ngOnDestroy(): void {
        this.subscription.unsubscribe();
    }           
    ngOnInit() {
       //some code
    }
}

我是不是在代码中遗漏了一些东西或者没有做对。为什么导航后订阅没有重置。 请指教 谢谢

正如第一条评论所暗示的,这似乎过于复杂。我希望这个例子可以提供一个更简单的设置来创建一个应用过滤器的搜索列表。

首先,让我们简化您的搜索结果服务。我通常遵循服务应尽可能通用的策略。因此,我们要做的就是请求并 return 完整的结果列表。

export class SearchresultsService {
  public searchresult$: Observable<ResultData[]>;

  constructor(private httpClient: HttpClient) {
    const url = `${environment.ssoUrl}api/SearchrResult`;
    this.searchresult$ = this.httpClient.get<ResultData[]>(url, { params, responseType: 'json' });
  }
}

服务文件是你可以定义可观察对象的地方,但你应该尽量避免订阅。将其留给依赖于服务数据的组件。

接下来,我创建了一个示例列表组件,将过滤器作为本地状态进行管理。我随意假设您的过滤器对象实际如何工作。

export class ListComponent {
  public searchResults$: Observable<ResultData[]>; 
  private filter = new BehaviorSubject<Filter>(new Filter());

  constructor(private searchService: SearchresultsService) {    
    this.searchResults$ = this.searchService.searchResult$.pipe(
      switchMap(results => this.filter.pipe(
        map(filter => results.filter(result => result[a] === filter[a]))
      ))
    );
  }

  public setFilter(criteria: any) {
    const newFilter = new Filter(criteria);
    this.filter.next(newFilter);
  }
}

让我们一步步来了解这个:

  1. 我们声明了一个使用默认空过滤器对象初始化的 BehaviorSubject。
  2. 我们添加了方法 setFilter(),允许您从同一个 BehaviorSubject 创建和发出新过滤器。
  3. 在我们的构造函数中,我们定义了一个可观察对象,它从我们的服务 HTTP 请求中获取所有数据。
  4. 我们使用 switchMap() 订阅我们的过滤器 BehaviorSubject 以获取最新的过滤值并应用它。

从这里,您可以使用 async 管道订阅组件模板中的 searchResult$ observable。这将在组件的整个生命周期中自动处理订阅和取消订阅事件。

<ul class="search-results">
  <li *ngFor="let result of searchResult$ | async">
    <!-- do things with {{result}} -->
  </li>
<ul>

现在,当您点击 CRUD 页面时,列表组件将与所有订阅一起销毁。当您返回时,filter BehaviorSubject 将使用默认的空白过滤器重新初始化。