Angular / TypeScript:如何初始化Observable矩阵

时间:2018-03-29 15:49:28

标签: angular typescript matrix observable

On Angular我在html模板中写了这段代码:

<div *ngFor='let itemArray of myObservableArray'>
  <div *ngFor='let item of itemArray | async'>
    {{item.value}}
  </div>
</div>

这是我的app.component.ts:

import { Component } from '@angular/core';
import { MyService, MyDataType } from './app.service';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular 5';
  myObservableArray: Observable<MyDataType[][]>;

  constructor(private myService: MyService) {
    this.getData(2);
  }

  getData(id: number) {
    if (!this.myObservableArray) {
      this.myObservableArray = new Array<MyDataType[]>();
      this.myObservableArray[id] = this.myService.getData(id);
    }
  }
}

这是app.service.ts的代码:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class MyService {

  mydata: MyDataType[] = [
    {"id":1, "value":"value_1_1"},
    {"id":1, "value":"value_1_2"},
    {"id":2, "value":"value_2_1"},
    {"id":2, "value":"value_2_2"},
    {"id":3, "value":"value_3_1"},
    {"id":3, "value":"value_3_2"}
  ];

  constructor() { }

  getData(id: number):Observable<MyDataType[]>
  {
    let data = new Observable<MyDataType[]>(observer => {

          setTimeout(() => {
              observer.next(this.mydata.filter(i => i.id == id));
          }, 4000);
    });
    return data;
  }
}

export class MyDataType
{
  public id: number;
  public value: string;
}

html模板正常工作,但我不明白为什么编译器会给我这个错误:

Type 'MyDataType[][]' is not assignable to type 'Observable<MyDataType[][]>'.
      Property '_isScalar' is missing in type 'MyDataType[][]'.
    (property) AppComponent.myObservableArray: Observable<MyDataType[][]>

我认为我对矩阵的初始化是错误的,但是对于Angular和TypeScript / JavaScript来说我是个新手,我想帮助我如何做到这一点。 在stackbliz上我放了完整的DEMO。感谢。

3 个答案:

答案 0 :(得分:1)

最后我解决了声明的问题:

10E7

并更改myObservableArray: Observable<Array<MyDataType[]>> = new Observable<Array<MyDataType[]>>(); 方法,如下所示:

getData
以这种方式

和html模板:

getData(id: number) {
  if (!this.myObservableArray[id]) {
      this.myObservableArray[id] = this.myService.getData(id);
  }
}

我已更新DEMO

答案 1 :(得分:0)

我已经将您的stackblitz分叉并简化了您的解决方案。查看Live demo

app.service

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { interval } from 'rxjs/observable/interval';
import { map } from 'rxjs/operators';


@Injectable()
export class MyService {

  mydata: MyDataType[] = [
    {"id":1, "value":"value_1_1"},
    {"id":1, "value":"value_1_2"},
    {"id":2, "value":"value_2_1"},
    {"id":2, "value":"value_2_2"},
    {"id":3, "value":"value_3_1"},
    {"id":3, "value":"value_3_2"}
  ];

  constructor() { }

  // use interval with map instead of setTimeout
  getData(id: number): Observable<MyDataType[]> {
    return interval(5000).pipe(map(i =>this.mydata.filter(i => i.id == id)))
  }
}

app.component

import { Component } from '@angular/core';
import { MyService, MyDataType } from './app.service';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular 5';
  myObservableArray: Observable<MyDataType[]>;

  constructor(private myService: MyService) {
    this.getData(2);
  }

  getData(id: number) {
    // you do not needed nested arrays here
    this.myObservableArray = this.myService.getData(id);
  }
}

app.component.html

<p>
    Wait 5 seconds to see some magic happen :)
</p>

<div *ngFor='let item of myObservableArray | async'>
    {{item.value}}
</div>

答案 2 :(得分:0)

import { Component } from '@angular/core';
import { MyService, MyDataType } from './app.service';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular 5';

在此您将myObservableArray声明为

Observable<MyDataType[][]

  myObservableArray: Observable<MyDataType[][]>;

  constructor(private myService: MyService) {
    this.getData(2);
  }

  getData(id: number) {
    if (!this.myObservableArray) {

但是你试着把

Array<MyDataType[]>() 
进入它。

      this.myObservableArray = new Array<MyDataType[]>();
      this.myObservableArray[id] = this.myService.getData(id);
    }
  }
}

你不能放

Array<MyDataType[]> 

进入

Observable<MyDataType[][]

这是编译器试图告诉你的。