использовать наблюдаемый угол, чтобы сообщить переменные изменения - PullRequest
0 голосов
/ 02 марта 2019

Я пытаюсь использовать Observable впервые, и я полностью сбит с толку.Есть так много маленьких примеров, и каждый делает по-своему.В двух словах, вот что я пытаюсь сделать: у меня есть компонент настроек, который позволяет пользователю изменять настройки, используемые в приложении.Использование локального хранилища, чтобы сохранить их, и я могу изменить их, сохранить их, прочитать при запуске и т. Д. Настройки работают отлично.Но теперь я хочу иметь возможность узнать, когда эти настройки изменились в режиме реального времени, чтобы я мог изменить некоторые DOM (например, названия) на основе новых настроек.Прямо сейчас я пытаюсь реализовать наблюдаемое из моей службы настроек обратно на app.component (где отображается заголовок), чтобы я мог обновить заголовок, как только он изменился.Но я даже не могу понять твой синтаксис правильно.Вот код settings.service:

import { Input } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
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;

  constructor(    private logger: LogService,
                  @Inject(LOCAL_STORAGE) private storage: StorageService) {
    this.settings = this.storage.get('TRACS3_SETTINGS');
    if ( this.settings === null ) {
      this.storage.set('TRACS3_SETTINGS', this.defaultSettings);
      this.settings = this.storage.get('TRACS3_SETTINGS');
    }

  }

  public getSettings(): any {
    //return this.storage.get('TRACS3_SETTINGS');
    //return this.storage.get('TRACS3_SETTINGS').asObservable();
    let settingsObservable = new Observable(observer => {
      return this.storage.get('TRACS3_SETTINGS');
    })
  }

  public saveSettings(settings: AppSettings): void{
    this.newSettings = settings;
    this.storage.set('TRACS3_SETTINGS', settings);
  }
}

и компонента:

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: AppSettings;
  defaultSettings: AppSettings;



  constructor(
    private titleService: TitleService,
    private appSettingsService: AppSettingsService,
    private matIconRegistry: MatIconRegistry,
    private domSanitizer: DomSanitizer,
    private adalService: AdalService,      
    private logger: LogService,
    private _wing: Observable<string>,
    @Inject(LOCAL_STORAGE) private storage: WebStorageService
        ){
    this.settings = this.appSettingsService.getSettings();

    adalService.init(environment.config);

    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 = this.appSettingsService.getSettings();

    this.logger.log(this.className, "Settings at startup: ", this.settings);
    if (this.settings.wing == null )
      this.settings = this.defaultSettings;
    _wing = this.settings.wing;
  }

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

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

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

}

Весь проект запущен на github на https://github.com/cpeddie/TRACS3.git

У кого-нибудь естьпростой пример использования наблюдаемой?

Спасибо ....

Ответы [ 2 ]

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

Механика кода

Проблема с вашим кодом заключается в том, что в вашем GetSettings() методе в вашем сервисе вы делаете конструируете Observable, но вы не вернуть его ...

public getSettings(): any {
   //return this.storage.get('TRACS3_SETTINGS');
   //return 
   this.storage.get('TRACS3_SETTINGS').asObservable();
   let settingsObservable = new Observable(observer => { 
       return this.storage.get('TRACS3_SETTINGS');
   })
}

add return settingsObservable;

Поэтому в конструкторе компонентов вы не подписываетесь на Observable instance вы создаете в сервисе.

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

Механика RxJS

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

Вы нашли последнее в своем компоненте, используя метод subscribe(), который доступен для всех наблюдаемых типов .Первый, однако, доступен только для определенных других наблюдаемых типов, которые добавляют больше функциональности.

Вам понадобится субъект .Это позволяет вам публиковать сообщения (с измененными настройками) на эту тему, используя метод next().Подписчики на наблюдаемое затем получат соответствующие сообщения, основанные на том, какой это тип предмета и как он себя ведет ... Список различных типов предметов см. В: http://reactivex.io/documentation/subject.html

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

Этот код должен работать:

@Injectable()
export class AppSettingsService {

    // 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) {
       var settings = this.storage.get('TRACS3_SETTINGS');

       if ( settings !== null ) {
           this._settings$.post(settings);
       } else {
           this.storage.set('TRACS3_SETTINGS', APPSETTINGS);
       }
    }

    public saveSettings(settings: AppSettings): void{
        this._settings$.next(settings)
        this.storage.set('TRACS3_SETTINGS', settings);
    }
}

Идея BehaviorSubject (_settings $) заключается в том, что вы публикуете значения на нем и наблюдаете изменения в других общедоступных настройках $ observable.

Каждый раз, когда вы изменяете значения в BehaviorSubject с помощью post () общедоступные наблюдаемые события.

Таким образом, вам даже не нужен метод getSettings (), поскольку вы подписываетесь на настройки $ в своем компоненте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...