Метод общей службы не вызывается в NgOnInit при загрузке компонента через метод router.navigate

У меня есть детальный обзор и контакт с дочерними компонентами. Я использовал общую службу для совместного использования массива ImageMap, который обновляется деталью после извлечения из службы при ее инициализации, подписки и доступа к дочерним элементам на их соответствующих методы инициализации. Когда я перехожу к дочерним компонентам, вручную вводя адрес в адресной строке, загружается фрагмент в ngOnInit дочернего компонента для установки значения массива из общей службы, тогда как при навигации с помощью router.navigate при нажатии кнопок, кроме этой части в NgOnInit все остальное загружается. Пожалуйста помоги мне с этим. Где я ошибся?

//component.html сведений об учетной записи

<h3>You selected brand {{item_name}}</h3>
<p>
    <button (click)="showOver()" class="btn btn-primary">Overview</button>
    <button (click)="showCon()" class="btn btn-info">Contact</button>
</p>
<router-outlet></router-outlet>
<button (click)="gotoAccounts()" class="btn btn-warning">Back</button>

//Обмен данными Service.ts

import { Injectable } from '@angular/core';
import { Subject,BehaviorSubject } from 'rxjs/Rx';

@Injectable({
    providedIn: 'root'
})
export class DatashareService {

  private dataObs$ =  new Subject();



     getData() {
        return this.dataObs$;
                }

updateData(data) {
    this.dataObs$.next(data);
                  }

 constructor() { }
}

//Компонент сведений об учетной записи.ts

import { Component, OnInit} from '@angular/core';
import { ActivatedRoute,Router,ParamMap } from '@angular/router';
import { ImageFetchService } from '../image-fetch.service';
import { DatashareService } from '../datashare.service';

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

public item_id;
public item_name;
public imageMap;
public errorMsg;
constructor(private route: ActivatedRoute,private router:Router,private 
imageService: ImageFetchService,
private dataService: DatashareService) { }

ngOnInit() {

//let id = parseInt(this.route.snapshot.paramMap.get('id'));
//this.item_id=id;

this.route.paramMap.subscribe((params: ParamMap)=>
{
  let id = parseInt(params.get('id'));
  this.item_id=id;
  let sel_name = params.get('name');
  this.item_name=sel_name;
  console.log(this.item_id,this.item_name);
}  )

 this.imageService.getImages().subscribe(data =>{ this.imageMap=data;

 this.dataService.updateData(this.imageMap);},
                                              error => this.errorMsg=error);




 }



  showOver()
  {
               let sel_name= this.item_name?this.item_name:null;

                this.router.navigate(['overview',{"name":sel_name}],
                {relativeTo:this.route})


   }

   showCon()
   {
       let sel_name= this.item_name?this.item_name:null;

       this.router.navigate(['contact',{"name":sel_name}],
       {relativeTo:this.route})

   }
  }

//Обзор учетной записи Component.ts

import { Component, OnInit,Input,OnDestroy,NgZone } from '@angular/core';
import {NgbCarouselConfig} from '@ng-bootstrap/ng-bootstrap';
import {map} from 'rxjs/operators';
import {HttpClient} from '@angular/common/http';
import { ActivatedRoute,Router,ParamMap } from '@angular/router';
import { DatashareService } from '../datashare.service';
import { Subscription } from 'rxjs/Subscription';


@Component({
  selector: 'app-account-overview',
  templateUrl: './account-overview.component.html',
  styleUrls: ['./account-overview.component.css'],
  providers: [NgbCarouselConfig]
})
export class AccountOverviewComponent implements OnInit,OnDestroy {
private subscription: Subscription = new Subscription();
public imageArray;
 public imageMap;
 public errorMsg;
 public selected_name;
  constructor(config: NgbCarouselConfig, private _http: HttpClient
  ,private route:ActivatedRoute,private dataService: DatashareService
  ,private zone:NgZone) {
    // customize default values of carousels used by this component tree
    config.interval = 2000;
    config.keyboard = false;
    config.pauseOnHover = false;
  }

  ngOnInit() {

   this.route.paramMap.subscribe((params: ParamMap)=>
        {
            let name =params.get('name');
            this.selected_name=name;
            console.log(this.selected_name);
        })

        this.subscription.add(this.dataService.getData().subscribe(data => { //<== added this

            this.zone.run(()=>{
                this.imageArray = data;
            })

        }))







  }

  ngOnDestroy() {
        // unsubscribe to ensure no memory leaks
        this.subscription.unsubscribe();
    }




}

person Mithil Mohan    schedule 06.08.2018    source источник


Ответы (2)


Попробуйте вернуть dataObs$ как Observable в DatashareService.ts и заменить Subject на BehaviorSubject.

import { BehaviorSubject } from 'rxjs/Rx';

export class DatashareService {

    private dataObs$ = new BehaviorSubject<any>({});

    getData() {
        return this.dataObs$.asObservable();
    }

    updateData(data) {
        this.dataObs$.next(data);
    }

    constructor() { }
}
person Lynx 242    schedule 06.08.2018
comment
Пробовал, результат тот же - person Mithil Mohan; 06.08.2018
comment
В консоли вообще нет ошибок, когда я перемещаюсь по нажатию кнопки, она не выполняется, когда я обновляю ее, нажимая ввод в адресной строке, она делает - person Mithil Mohan; 06.08.2018
comment
Ваш код действительно входит в метод ngOnInit? Можете ли вы проверить это, поместив console.log() в самую верхнюю строку кода внутри ngOnInit? - person Lynx 242; 06.08.2018
comment
Да, все, кроме этой части, выполняется, чтение параметров и операторы консоли работают, только эта часть не обрабатывается - person Mithil Mohan; 06.08.2018
comment
Хорошо, следующий вопрос. Печатает ли console.log() что-нибудь внутри this.subscription.add(this.dataService.getData().subscribe(data => {... ? Вы можете получить доступ к data там? - person Lynx 242; 06.08.2018
comment
Нет, это именно то, в чем заключается моя проблема, она не входит в этот фрагмент или просто эта часть не выполняется. - person Mithil Mohan; 06.08.2018
comment
Странно. Ваш код выглядит нормально. Последняя идея. Замените тему в службе на BehaviorSubject. - person Lynx 242; 06.08.2018
comment
Для ясности в BehaviorSubject см.: stackoverflow.com/questions/39494058/ - person Mithil Mohan; 06.08.2018
comment
Пожалуйста. Я обновил свой ответ. Пожалуйста, не забудьте отметить это как решение. Заранее спасибо. - person Lynx 242; 06.08.2018
comment
Использование объекта поведения приводит к тому, что метод подписки срабатывает дважды с начальным значением {} и обновленным значением, поэтому лучшей практикой, которую я обнаружил, является использование ReplaySubject, который очень похож на субъект поведения, но не требует начального значения, для простых использование темы воспроизведения, см.: stackoverflow.com/questions/ 44693438/ - person Mithil Mohan; 06.08.2018

Использование BehaviourSubject дважды вызывало срабатывание метода подписки в дочернем компоненте, сначала с начальным значением {}, а затем с последним обновленным значением. Поэтому я изменил его на ReplaySubject, которому не нужно начальное значение.

import { ReplaySubject } from 'rxjs/Rx';

export class DatashareService {

    private dataObs$ = new ReplaySubject<any>(1);

    getData() {
        return this.dataObs$.asObservable();
    }

    updateData(data) {
        this.dataObs$.next(data);
    }

    constructor() { }
}
person Mithil Mohan    schedule 06.08.2018