如何将项目添加到rxjs可观察数组?

时间:2019-10-13 14:05:58

标签: angular rxjs

我有一个从服务器获取数据的组件。我的服务有一个BehaviorSubject<any[]>([])来获取数据。

export class AppComponent {
  items: Observable<any[]>;

  constructor(private service: MyService) {
    this.items = service.getItems();
    // this items format is like: `[{id:1,name:'cat'},{id:2,name:'dog'}]`
  }

  addItem(item:any){
   // add item to `this.items` observable array ???
  }

  removeItem(item:any){
   // remove item from `this.items` observable array ???
  }
}

我的服务如下:

@Injectable()
export class MyService{
    private items = new BehaviorSubject<any[]>([]);

    constructor(private http: HttpClient) {
      this.loadItems();
    }

    private loadItems() {
      this.http.get<any[]>('/api/items')
        .subscribe((i) => this.items.next(i));
    }

    getItems() {
      return this.items.asObservable();
    }

    addItem(item: any) {
      return this.http
        .post<any>('/api/items', item)
        .subscribe(() => this.loadItems());
    }
}

我需要向该可观察数组添加添加和删除项目,但是无法执行。该服务可以将数据添加到服务器,但是我需要添加数组而不发送到服务器。这可能吗?

2 个答案:

答案 0 :(得分:1)

您需要先订阅观察值并返回值,然后才能进行任何进一步的操作。

例如

import { Component, OnInit } from '@angular/core';

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

export class AppComponent implements OnInit {
  items: any[];

  constructor(private service: MyService) {

  }

  ngOnInit() {
    this.service.getItems().subscribe(res => {
      console.log(res);
      this.items = res;
    });
  }

addItem(){
  // this.items.push(someObject)
}


}

答案 1 :(得分:1)

在您的情况下,您不需要定义BehaviourSubject,因为您不需要维护应用程序的状态。因此,您可以简单地使用以下代码。

在服务组件中,仅编写服务。因为服务是单例,只有一次被初始化。

@Injectable()
export class SomeDataService {    

    //Made this as observable, But when you use httpClient, No need to use Observable.of(), you can directly return like this.http.get<any[]>('/api/items')

    myData=Observable.of([{id:1,name:'cat'},{id:2,name:'dog'},{id:3,name:'rabbit'}])
    constructor() {     
    }

    loadItems() {
      // in your case, return this.http.get<any[]>('/api/items')
      return this.myData;
    }
}

在AppComponent中

export class AppComponent implements OnInit {
    counter=4;
    mydata=[]; //No point to make this as Observable array

    constructor(private _service: SomeDataService) { }

    public ngOnInit(): void {
        this._service.loadItems().subscribe(res=>{     
            this.mydata=res;       
        })  
    }

    addData(){
        let increment=this.counter++
        let data={id:increment,name:increment+"data"}
        this.mydata.push(data)
    }

    removeData(item){
        let index=this.mydata.indexOf(item)
        this.mydata = this.mydata.filter((val,i) => i!=index); 
    }
}

在html中,

<button (click)="addData()">Add data</button>

<table>
    <tr>
        <th>Id</th>
        <th>Name</th>
        <th>Action</th>
    </tr>
    <tr *ngFor="let data of mydata;let i=index;">
        <td>{{data.id}}</td>
        <td>{{data.name}}</td>
        <td><button (click)="removeData(data)">Remove data</button></td>
    </tr>
</table>

点击此处查看演示Stackblitz 希望对您有帮助