Angualar 4 observable - подписка не работает при навигации по маршруту, но работает при обновлении страницы - PullRequest
0 голосов
/ 10 октября 2018

Я очень плохо знаком с угловой.В рамках обучения я создаю небольшое приложение.

У меня есть следующие компоненты:

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.

Компоненты Dashboard, SetNewJob и ManageJob загружаются с использованием розетки-маршрутизатора.

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 () Подписаться на CurrentJob из jobService, и отображается текущее задание

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

Теперь проблемакогда пользователь входит в систему, будет отображаться страница панели инструментов.Если пользователь хочет изменить активную работу, он должен перейти к установке новой работы.Когда происходит навигация, текущая активная работа не выбрана в раскрывающемся списке.Но если страница обновляется, в раскрывающемся списке отображается активное задание.т.е. подписка происходит только при обновлении страницы.

Я попытался добавить указанный выше код (код подписки) в ngOnInit () SetNewJob.component.ts.

Та же проблема возникает и в компоненте 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 голосов
/ 10 октября 2018

Проблема возникает из-за того, что ваш AppComponent устанавливает задание до того, как ваш HeaderComponent подписывается на него.Вы можете изменить свой Subject на BehaviorSubject, так что последний выпуск будет доступен по подписке:

Замените это: CurrentJob = new Subject <Job>();

На: CurrentJob = new BehaviorSubject<any>(null);

ps вы можете заменить null на некоторый начальный объект, который вы можете показать своим пользователям.Создайте класс Job по умолчанию:

defaultJob: Job = { ... }

И установите начальное значение для BehaviorSubject:

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

Полезно для отображения информации по умолчанию, если данные не поступилиеще и должно быть сделано, чтобы соответствовать требованию, если вы используете пользовательскую аннотацию Type субъекта.

...