по-прежнему борется с угловой наблюдаемой - PullRequest
0 голосов
/ 04 марта 2019

Я думал, что наконец начал понимать это, но, очевидно, я все еще что-то упускаю.Я пытаюсь создать наблюдаемое с помощью BehaviorSubject в службе настроек приложения.Я думаю, что я понимаю шаги, чтобы правильно создать наблюдаемое.Но теперь, когда у меня появилось несколько новых значений для обновления наблюдаемого, Angular выкручивает время выполнения, сообщая мне, что следующий не определен для моей службы поведения.

Вот обновленный код:

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 {
  className: string;
  settings: AppSettings;

  @Input()
    // Use of BehavioirSubject. This is where you post values into
    private _settings$: BehaviorSubject<AppSettings> = new BehaviorSubject<AppSettings>(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.className = this.constructor.toString().match(/\w+/g)[1];
      /*
       * First, we check to see if this is the first time the app has
       * been run on this machine. If it is, then local storage will return
       * null when we ask for the settings. We'll populate local storage
       * with the default settings values before we continue on setting up 
       * the service.
       */
       this.settings = this.storage.get('TRACS3_SETTINGS');
       if ( this.settings == null ) {
         try {
          this.storage.set('TRACS3_SETTINGS', APPSETTINGS);
         }
         catch(e) {
           console.log(this.className, 'Machine does not support local storage. ');
         }
       }

       /* 
          AppSettings are now initialized, set the initial value of them for all other
          components will use to monitor them.
        */
       console.log(this.className, 'about to set observable iniitial values');
       this.settings = this.storage.get('TRACS3_SETTINGS');
       this._settings$ = this.storage.get('TRACS3_SETTINGS');
       console.log(this.className, 'just changed observabe to ',     this._settings$);
}


    public saveSettings(settings: AppSettings): void{
      console.log(this.className, 'saving settings in service, new settings: ', settings);
      //this._settings$.post(settings)
      this.storage.set('TRACS3_SETTINGS', settings);
      this._settings$.next( settings );
    }


  //public getSettings(): AppSettings {
    //eturn this.storage.get('TRACS3_SETTINGS');
  //}

}

Теперь я получаю разные ошибки.Если я попытаюсь установить Observer с этой строкой кода:

this._settings$ = this.settings;

, я получу сообщение об ошибке:

Type 'AppSettings' is missing the following properties from type 'BehaviorSubject<AppSettings>': _value, value, _subscribe, getValue, and 19 more.ts(2740)

Но когда я поставлю его на значение, показанное выше (= это.storage.get ...) Теперь я получаю ошибку во время выполнения

enter image description here

Я нахожусь в своем уме здесь.Я не то, что еще, кроме, может быть, отказаться от угловых в целом.

Ответы [ 2 ]

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

Я спросил одного из инженеров (@JavRufus) на работе об этом (я не программировал много лет и снова учу себя искусству).Он придумал для меня следующий пример.

appsettings.service.ts:

 import { Injectable } from '@angular/core';
 import { BehaviorSubject } from 'rxjs';
 import { AppSettings } from '../model/appsettings';

 @Injectable({
   providedIn: 'root'
 })

 export class AppSettingsService {

   private appSettings: AppSettings;
   private _appSettingsSubject: BehaviorSubject<AppSettings> = new BehaviorSubject(this.appSettings);

   constructor() {
     if (localStorage && localStorage.getItem('APP-SETTINGS') !== 'undefined') {
       this.appSettings = JSON.parse(localStorage.getItem('APP-SETTINGS'));
     } else {
       this.appSettings = new AppSettings();
       localStorage.setItem('APP-SETTINGS', JSON.stringify(this.appSettings));
     }
     this._appSettingsSubject.next(this.appSettings);
   }

   get behaviorSubject() {
     return this._appSettingsSubject;
   }

   set updateAppSettings(newAppSettings: AppSettings) {
     console.log('Service; update sessings:  ' + this.appSettings.userName + '; ' +      this.appSettings.password);
     this.appSettings = newAppSettings;
     if (localStorage) {
       localStorage.setItem('APP-SETTINGS', JSON.stringify(this.appSettings));
     }
     this._appSettingsSubject.next(this.appSettings);
   }

 }

sample-client.component.ts:

 import { Component, OnInit } from '@angular/core';
 import { AppSettings } from '../model/appsettings';
 import { AppSettingsService } from '../config/appsettings.service';

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

   appSettings: AppSettings;

   constructor(private appSettingsService: AppSettingsService) {}

   ngOnInit() {
     this.appSettings = this.appSettingsService.behaviorSubject.getValue();
   }

   updateAppSettings() {
     console.log('Client; update sessings:  ' + this.appSettings.userName + '; ' +      this.appSettings.password);
     this.appSettingsService.updateAppSettings = this.appSettings;
   }

 }

наконец, за которым следует sample-receiver.component.ts:

 import { Component, OnInit } from '@angular/core';
 import { AppSettings } from '../model/appsettings';
 import { AppSettingsService } from '../config/appsettings.service';
 import { Subscription } from 'rxjs';

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

   appSettings: AppSettings;

   appSettingsSub: Subscription;

   constructor(private appSettingsService: AppSettingsService) {}

   ngOnInit() {
     this.appSettings = this.appSettingsService.behaviorSubject.getValue();

     this.appSettingsSub =      this.appSettingsService.behaviorSubject.asObservable().subscribe(value => {
       this.appSettings = value;
     });
   }

 }

и, конечно, класс appsettings.ts

 export class AppSettings {

   userName: string;
   password: string;

   constructor() {}

 }

Используйте это в качестве отправной точки, и у вас не должно возникнуть проблем при настройке службы для хранения appSettings, а затем наличия компонентаизменить их и компонент, чтобы получить уведомление об их изменении.

Надеюсь, это поможет кому-то другому, не тратящему 3 дня, искать решение, как я!

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

В вашем конструкторе вы переназначаете _settings$ с this._settings$ = this.storage.get('TRACS3_SETTINGS');

Теперь поле равно значению TRACS3_SETTING, и я думаю, что это не какой-либо вид наблюдаемого.

Вы должны использовать this._settings$.next(this.storage.get('TRACS3_SETTINGS'));, чтобы изменить его внутреннее значение

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