商店从服务接收空数据

时间:2018-03-24 10:30:29

标签: angular

对于基本商店实现,我的服务尝试加载任务对象。在map中,任务按其ID进行排序,并在do中将任务分派到商店。但是,在商店中数据为空(TypeError: action.data is undefined)。 为什么?

import { Injectable, Inject } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';

import { LOAD, EDIT, ADD, REMOVE, TaskStore } from '../services/stores/index';
import { Task } from '../domain/task';

@Injectable()
export class TaskService {

  private headers = new HttpHeaders();
  private tasksUrl = 'http://localhost:8090/task/tasks/';

  tasks$: Observable<Task[]>;

  constructor(private httpClient: HttpClient, private taskStore: TaskStore) {
    this.headers = this.headers.set('Content-Type', 'application/json');
    this.headers = this.headers.set('Accept', 'application/json');

    this.tasks$ = taskStore.items$;
  }

  getTasks(): Observable<Task[]> {
    this.httpClient.get<Task[]>(this.tasksUrl).map((result: any) => {
      console.log('fetched ' + result._embedded.tasks.length + ' Tasks from server');
      result._embedded.tasks.sort((a, b) => a.id - b.id);
    }).do((tasks) => {
      this.taskStore.dispatch({ type: LOAD, data: tasks });
    });

    return this.tasks$;
  }

}

商店:

import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Task } from '../../models/model-interfaces';

export const LOAD = 'LOAD';
export const ADD = 'ADD';
export const EDIT = 'EDIT';
export const REMOVE = 'REMOVE';

export class TaskStore {
  private tasks: Task[] = [];
  items$ = new BehaviorSubject<Task[]>([]);

  dispatch(action) {
    console.log("dispatched")
    this.tasks = this._reduce(this.tasks, action);
    this.items$.next(this.tasks);
  }

  _reduce(tasks: Task[], action) {
    switch (action.type) {
      case LOAD:
        return [...action.data];
      case ADD:
        return [...tasks, action.data];
      case EDIT:
        return tasks.map(task => {
          const editedTask = action.data;
          if (task.id !== editedTask.id) {
            return task;
          }
          return editedTask;
        });
      case REMOVE:
        return tasks.filter(task => task.id !== action.data.id);
      default:
        return tasks;
    }
  }
}

2 个答案:

答案 0 :(得分:0)

看看ngrx。这是在角度中使用redux的解决方案。

答案 1 :(得分:0)

解决方案的工作原理如下。在TaskListComponent中显示任务列表(*ngFor="let task of tasks$ | async")。它订阅/销毁商店的items$ - BehaviorSubject上的订阅(对于商店,请查看原始帖子)。在TaskListComponent的ngOnInit中,调用服务以从服务器获取任务。一旦服务收到它们,它们就会被发送到taskStore,它执行调度并将数据(this.items$.next(this.tasks))发送到BehaviorSubject的订阅观察者。

TaskListComponent

tasks$: Observable<Task[]>;

constructor(private taskService: TaskService) { }

ngOnInit() {
  this.tasks$ = this.taskService.tasks$;
  this.taskService.getTasks();
}

TaskService

tasks$: Observable<Task[]>;

constructor(private httpClient: HttpClient, private taskStore: TaskStore) {
  this.tasks$ = taskStore.items$;
}

getTasks() {
    this.httpClient.get<Task[]>(TASKS_URL).map((result: any) => {
      return result._embedded.tasks.sort((a, b) => a.id - b.id);
    }).subscribe((tasks) => {
      this.taskStore.dispatch({type: LOAD, data: tasks});
    });
  }

不知道为什么原帖被降级了。如果我可以添加一些内容以使其更清晰,更有帮助/有用,请告诉我。