首页 > 解决方案 > 如何将项目添加到 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());
    }
}

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

标签: angularrxjs

解决方案


在您的情况下,您不需要定义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;
    }
}

在应用组件中

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


推荐阅读