Потратили впустую весь день и больше, пытаясь заставить Angular Observable работать - PullRequest
0 голосов
/ 03 марта 2019

Помощь!Я потратил впустую весь день и большую часть вчерашнего дня, пытаясь заставить наблюдаемое работать в моем приложении Angular.У меня есть компонент, который используется для изменения пользовательских настроек / конфигурации приложения, и я хочу иметь возможность уведомлять другие компоненты при изменении настроек.Чем больше я читаю, тем больше путаюсь.Вот мой код контейнера настроек:

import { Component, OnInit, Input } from '@angular/core';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import { Observable } from 'rxjs';
import { MatSelectModule, SELECT_ITEM_HEIGHT_EM } from     '@angular/material/select';


import { AppSettings } from '../../shared/app-settings'
import { AppSettingsService } from '../../services/app-settings.service';
import { APPSETTINGS } from '../../shared/defaultSettings';
import { ThemeService } from '../../services/theme.service';
import { LogService } from 'src/app/services/app-log.service';

@Component({
  selector: 'app-settings-container',
  templateUrl: './settings-container.component.html',
  styleUrls: ['./settings-container.component.scss']
})
export class SettingsContainerComponent implements OnInit {
  className: string;

  settings: AppSettings;

  @Input()
  defaultSettings = APPSETTINGS;

  themes = [
    { value: 'DEFAULT-THEME', label: 'blue' },
    { value: 'LIGHT-THEME', label: 'light' },
    { value: 'NATURE-THEME', label: 'nature' },
    { value: 'BLACK-THEME', label: 'dark' }
  ];

  wings = [
        { value: 'ALWG', label: 'Alabama Wing' },
        { value: 'WYWG', label: 'Wyoming Wing' },
  ];

  @Input()
  title: string;

  constructor(private appSettingsService: AppSettingsService,
              private logger: LogService,
              private themeService: ThemeService) { }

  ngOnInit() {  
    this.className = this.constructor.toString().match(/\w+/g)[1];
    this.settings = this.appSettingsService.getSettings();
  }

  saveSettings( event ) {
    this.logger.debug(this.className, 'saveSettings, settings:', this.settings);
    this.appSettingsService.saveSettings(this.settings);

  }

}

Все это прекрасно работает, и все мои обратные вызовы (удаленные для краткости) работают нормально.Служба настроек короткая и приятная, как показано ниже:

import { Input } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { BehaviorSubject } from 'rxjs';
import { AppSettings } from '../shared/app-settings';
import { APPSETTINGS } from "../shared/defaultSettings";
import { Inject, Injectable } from '@angular/core';
import { LOCAL_STORAGE, StorageService } from 'angular-webstorage-service';
import { LogService } from 'src/app/services/app-log.service';


@Injectable()
export class AppSettingsService {

  @Input()
  defaultSettings = APPSETTINGS;
  settings: Observable<AppSettings>;
  newSettings: AppSettings;
    // Use of BehavioirSubject. This is where you post values into
    private _settings$: BehaviorSubject<AppSettings> = new     BehaviorSubject(APPSETTINGS)
    // Settings observer. This is where you read from outside
    settings$: Observable<AppSettings> = this._settings$.asObservable();

    constructor(private logger: LogService,
                @Inject(LOCAL_STORAGE) private storage: StorageService) {
       this.newSettings = this.storage.get('TRACS3_SETTINGS');

       if ( this.newSettings !== null ) {
           this._settings$.next(this.newSettings);
       } else {
               this.storage.set('TRACS3_SETTINGS', APPSETTINGS);
           this.newSettings = this.storage.get( 'TRACS3_SETTINGS');
           console.log('about to change observable');
           this._settings$.next( this.newSettings );
           console.log('just changed observabe to ', this.newSettings);
       }
    }
    public saveSettings(settings: AppSettings): void{
      console.log('saving settings in service');
      //this._settings$.post(settings)
      this._settings$.next(settings);
      this.storage.set('TRACS3_SETTINGS', settings);
    }


  public getSettings(): Observable<AppSettings> {
    return this.storage.get('TRACS3_SETTINGS');
  }

}

Настройки правильно сохраняются в локальном хранилище и читаются при запуске, как и должны.Однако я пытаюсь добиться того, чтобы мой app.com уведомлял об изменении настроек (заголовок панели навигации является одним из параметров).Но я бился головой о стену, пытаясь понять, как это сделать.Вот мой код app.component:

import { Component, OnInit } from '@angular/core';
import { MatIconRegistry } from "@angular/material/icon";
import { DomSanitizer } from "@angular/platform-browser";
import { Inject } from '@angular/core';
import { Observable } from 'rxjs';
import { AdalService } from 'adal-angular4';
import { environment } from '../environments/environment';

import { AppSettings } from './shared/app-settings'
import { AppSettingsService } from './services/app-settings.service';
import { APPSETTINGS } from './shared/defaultSettings';
import { LogService } from 'src/app/services/app-log.service';

import {LOCAL_STORAGE, WebStorageService} from 'angular-webstorage-service';

import { Aircraft } from "./shared/aircraft";
import { Content } from '@angular/compiler/src/render3/r3_ast';
import {TitleService } from './services/title.service';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent implements OnInit{
  className: string;
  aircraft: Aircraft[];
  isAuthenticated$:         Observable<boolean>;
  settings$: Observable<AppSettings>;
  newSettings: AppSettings;
  defaultSettings: AppSettings;



  constructor(
    private titleService: TitleService,
    public appSettingsService: AppSettingsService,
    private matIconRegistry: MatIconRegistry,
    private domSanitizer: DomSanitizer,
    private adalService: AdalService,      
    private logger: LogService,
    @Inject(LOCAL_STORAGE) private storage: WebStorageService
    ){
    this.settings$ = this.appSettingsService.getSettings();
    console.log('settings$: ', this.settings$);
    adalService.init(environment.config);

    this.matIconRegistry.addSvgIcon(
      "historical-tracking-black-48",
      this.domSanitizer.bypassSecurityTrustResourceUrl("../assets/historical-    tracking-black-48.svg")
);
    this.matIconRegistry.addSvgIcon(
      "historical-tracking-black-48-inactive",
      this.domSanitizer.bypassSecurityTrustResourceUrl("../assets/historical-tracking-black-48-inactive.svg")
    );
    //this.appSettingsService.getSettings().subscribe(newSettings =>     this.settings = newSettings);
  } 

  ngOnInit(){
    this.className = this.constructor.toString().match(/\w+/g)[1];

    this.adalService.handleWindowCallback();
    this.logger.debug(this.className, "adal userInfo: ",     this.adalService.userInfo);

        this.settings$ = new Observable(observer => {
          console.log('in observer');
        })

    let subscription = this.settings$.subscribe(
      newSettings => console.log('NewSettigns: ',newSettings),      
    )
    this.logger.log(this.className, "Settings at startup: ", this.settings);

    this.appSettingsService.getSettings().subscribe((newSettings) => {
      console.log('settings have changed, new settings are:', newSettings);
    })
  }

  login() {
    this.adalService.login();
  }

  logout() {
    this.adalService.logOut();
  }

  get authenticated(): boolean {
    return this.adalService.userInfo.authenticated;
  }

}

У меня работает аутентификация (что, как мне показалось, будет сложно - не было), но я не могу на всю жизнь получить наблюдаемую работу, которую ямысль должна была быть простой.Проблема в том, что, кажется, существует так много разных способов сделать это, все, что я продолжаю читать, приводит меня в замешательство.Может ли кто-нибудь указать мне правильное направление?

Спасибо ....

1 Ответ

0 голосов
/ 03 марта 2019

Вы очень близки!Ваша проблема в том, что вы на самом деле не подписываетесь на наблюдаемую из AppSettingsService.

Раскомментируйте эту строку:

\\this.appSettingsService.getSettings().subscribe(newSettings => this.settings = newSettings);

, но измените ее на:

this.appSettingsService.settings$.subscribe(newSettings => this.settings = newSettings);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...