簡體   English   中英

Angular 值更改后未定義的可觀察值

[英]Angular observable value undefined after value changes

類型錯誤:無法讀取 null 的屬性“ip”

提供者.ts

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { DeviceInterface } from '../interfaces/Device';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class DeviceService {

  private _devices = new BehaviorSubject<DeviceInterface[]>([]);
  private baseUrl = 'api/monitoring';
  private dataStore: { devices: DeviceInterface[] } = { devices: [] };
  readonly devices = this._devices.asObservable();

  constructor(private http: HttpClient) { }

  loadAll() {
    this.http.get<DeviceInterface[]>(`${this.baseUrl}/devices`).subscribe(
      data => {
        this.dataStore.devices = data;
        this._devices.next((<any>Object).assign({}, this.dataStore).devices);
      },
      error => console.log('Could not load todos.')
    );
  }

  create(device: DeviceInterface) {
    this.http
      .post<DeviceInterface>(`${this.baseUrl}/add`, device)
      .subscribe(
        data => {
          this.dataStore.devices.push(data);
          this._devices.next((<any>Object).assign({}, this.dataStore).devices);
        },
        error => console.log('Could not create todo.')
      );
  }


}

組件.ts

import { Component, OnInit } from '@angular/core';
import { DialogService, Dialog } from '../providers/dialog.provider';
import { fadeInOut } from '../app.component.animation';
import { AppComponent } from '../app.component'
import {
  LanguageService,
} from '../providers/language.provider';

import { DeviceService } from '../providers/device.provider';
import { DeviceInterface } from '../interfaces/Device';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Component({

  selector: 'app-monitoring',
  templateUrl: './monitoring.component.html',
  styleUrls: ['./monitoring.component.scss'],
  animations: [fadeInOut],
})

export class AppMonitoring implements OnInit {

  dialog: Dialog;
  ShowDevices: boolean;
  devices: Observable<DeviceInterface[]>;

  constructor(
    public language_service: LanguageService,
    public  device_service: DeviceService,
    private dialog_service: DialogService,
    app: AppComponent
  ) {

    app.done$.pipe().subscribe(result => {
      this.ShowDevices = true;
    });

  }

  ngOnInit() {
    this.devices = this.device_service.devices;
    this.device_service.loadAll();
    this.ShowDevices = false;
    this.dialog_service.DialogState.subscribe(dialog => this.dialog = dialog);
  }

  AddDevice() {
    this.dialog = Dialog.DIALOG_ADD;
    this.dialog_service.ChangeDialog(this.dialog);
  }

  Scan() {
    this.dialog = Dialog.DIALOG_SCAN;
    this.dialog_service.ChangeDialog(this.dialog);
  }

}

html 模板

  <div [@fadeInOut] *ngIf="ShowDevices">

    <div class="box-header" style="margin-bottom:15px;">
      <div class="div-right" style="line-height: 35px;">

        <a href="#" onclick="return false;" (click)="AddDevice()" class="pull-right"><i matTooltipPosition="below" class="fa fa-plus"></i> </a>
        <a href="#" onclick="return false;" (click)="Scan()" class="pull-right"><i matTooltipPosition="below" class="fa fa-search"></i> </a>
      </div>
    </div>

    <app-device class="flexItemSensor" *ngFor="let device of devices | async; index as i;" [ip]="device?.ip" [name]="device?.name"> </app-device>
  </div>

當我添加你使用

this.device_service.create(post);

添加了新項目,但輸入值沒有收到以下錯誤,應用程序凍結。

使用以下代碼在第三個組件中調用 create function 本身

  AddDevice() {

    let post: DeviceInterface = {
      ip: this.AddDeviceForm.value.ip,
      name: this.AddDeviceForm.value.name,
    }
    this.device_service.create(post);

  }

無法讀取 null 的屬性“ip”

我知道該項目已成功存儲在數據庫中,當我重新啟動程序時,我可以看到帶有他的值的新項目,添加顯示他的值的項目的正確方法是什么?

此致!

編輯:我嘗試在 ngOnInit() 中添加以下代碼,並且在添加的設備上,設備的新值確實是 null

 ngOnInit() {

     this.device_service.devices.subscribe(devices => {
      console.log(devices);
    } ); 
    }

編輯 2:問題已解決,原來在后端 controller 應該返回以下內容:

        return Ok(device);

BehaviorSubject將立即發出它在訂閱時持有的當前值。 async觸發訂閱時,可觀察對象的值仍然是默認值(空數組[] )。 所以沒有ip屬性。

選項1

使用安全導航運算符?. 在嘗試訪問它的屬性之前檢查該值是否已定義

<app-device *ngFor="let device of devices | async; index as i;"  [ip]="device?.ip" [name]="device?.name"> </app-device>

選項 2

嘗試使用*ngIf指令預先檢查數組是否為非空。

<ng-container *ngIf="(devices | async) as devicesData">
  <ng-container *ngIf="devicesData.length > 0">
    <app-device *ngFor="let device of devicesData; index as i;"  [ip]="device.ip" [name]="device.name"> </app-device>
  <ng-container>
<ng-container>

嘗試這個

 <app-device *ngFor="let device of devices | async; index as i;"  [ip]="device?.ip" [name]="device?.name"> </app-device>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM