可观察到的Angualar 4-订阅不适用于“路线导航”,但适用于页面刷新

时间:2018-10-10 05:54:09

标签: angular .net-core

我对棱角非常陌生。作为学习的一部分,我正在构建一个小型应用程序。

我具有以下组件:

App Component -  Root Component
Header Component - Displays Active Job (Based on the logged in userId), Title etc
Menu Component - Displays available Menus(ex:"Dashboard", "Set New Job","Manage Job")
Dashboard Component - Display Reports for the Active Job
SetNewJob Component - To Set a new Job as Active
ManageJob Component - To Add/Edit a few fields relevant to the job.

仪表板,SetNewJob和ManageJob组件是使用router-outlet加载的。

App.component.html

<div class='container-fluid'>
    <app-header>loading</app-header>
    <hr style="border: solid 1px black!important;">
    <app-menu></app-menu>
    <router-outlet></router-outlet>
</div>

App.component.ts-构造函数进行服务调用以查找用户的活动作业并将其设置为当前作业

    import { Component,OnInit } from '@angular/core';
    import { Subscriber } from '../../../../node_modules/rxjs/Subscriber';
    import { Subject, Observable }    from 'rxjs';

    import {JobService} from '../../_services/job.service';
    import { Job } from '../../_models/job';

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

        CurrentJob:Job

        constructor(private _jobService:JobService) {
            this._jobService.getUserJob(123).subscribe(job=>{
                this.CurrentJob = job; 
                this._jobService.setCurrentJob(job);
            })        
         }

        ngOnInit() { }  
    }

Header.Component.ts-ngOnInit()从jobService订阅CurrentJob并显示当前作业

    import { Component, OnInit, Input } from '@angular/core';
    import { Subject, Observable }    from 'rxjs';
    import {JobService} from '../../_services/job.service';
    import { Job } from '../../_models/job';


    @Component({
      selector: 'app-header',
      templateUrl: './header.component.html',
      styleUrls: ['./header.component.css']
    })
    export class HeaderComponent implements OnInit {
      CurrentJob:Job   

      constructor(private _jobService:JobService) {     
      }  

      ngOnInit() { 
        this._jobService.getCurrentJob().subscribe(job => { this.CurrentJob = job; });
      } 

    }

SetNewJob.component.html

Contains a dropdown for the available jobs for the user.
on load, it should select a currently active job(ie the job which is displayed in the Header) by default.
for that, i have added below code in Constructor of SetNewJob.component.ts

this._jobService.getCurrentJob().subscribe(job => { 
    this.CurrentJob = job;
    this.SelectedJobId=job.jobId;
});

现在的问题是,当用户登录时,将显示“仪表板”页面。如果用户要更改活动作业,则应导航到“设置新作业”。 导航发生时,在下拉菜单中未选择当前活动的作业。但是,如果刷新页面,则下拉菜单将显示活动的作业。 即订阅仅在页面刷新时发生。

我尝试通过在SetNewJob.component.ts的ngOnInit()中添加以上代码(订阅代码)。

ManageJob组件中也发生了相同的问题。 该组件根据活动作业填充一些下拉菜单。下拉列表不会在导航中填充,但在页面刷新时,一切正常。

Job.Service.ts的代码

    import { Http, Response } from '@angular/http';

    import {HttpClient} from '@angular/common/http'
    import { Injectable } from '@angular/core';
    import { Subject, Observable }    from 'rxjs';

    export const ROOT_URL:string="http://localhost:5000/api"; 

    import 'rxjs/add/operator/map';

    import {Job} from '../_models/job'
    import {Area} from '../_models/area'

    @Injectable()
    export class JobService {    
        Job:Observable<Job>;    
        CurrentJob = new Subject<Job>();
        private SelectedJob:Job;

        constructor(private _http: Http,private httpClient: HttpClient){           

        } 

        getUserJob(userId:number):Observable<Job>{        
            return this._http.get(ROOT_URL + "/User/CurrentJob/",
                    { 
                        params: {
                            'userId':userId.toString()
                        }
                    }
                ).map((res : Response) =>res.json())         
                .catch(this.errorHandler);           

        }

        getCurrentJob():Observable<any>{   

            return this.CurrentJob.asObservable();         
        }

        setCurrentJob(job: any) {              
            this.CurrentJob.next(job); 
            this.SelectedJob=job;       
        }

        errorHandler(error: Response) {       
            return Observable.throw(error);  
        }  
    }

实际上发生了什么? 为什么订阅在路线导航上失败。有没有其他选择可以做到这一点。我可能还需要在其他页面中使用currentJob对象。

请帮助。

1 个答案:

答案 0 :(得分:1)

发生此问题是因为您的AppComponent在HeaderComponent订阅之前设置了一个作业。您可以将Subject更改为BehaviorSubject,以便最后一次发射将成为opon订阅:

替换此: CurrentJob = new Subject <Job>();

进入: CurrentJob = new BehaviorSubject<any>(null);

p.s。您可以将null替换为一些可以显示给用户的初始对象。创建默认的Job类:

defaultJob: Job = { ... }

并将初始值设置为BehaviorSubject:

CurrentJob = new BehaviorSubject<Job>(this.defaultJob);

如果数据尚未到达,则可用于显示默认信息,如果您使用“主题”的“类型”自定义注释,则必须执行此操作才能满足要求。