angular2 / rxjs / redux重新实现 - 路由更改与可观察

时间:2015-11-13 09:20:13

标签: javascript angular redux rxjs

我试图在angular2应用程序中对rxjs中的redux进行基本的重新实现。

此时它基本上只是我在互联网上找到的几件事情,this plunker代表角度DI,this for file structurethis for combineReducers,最后{{3 }}

有'我遇到的几个问题,但这是目前最大的问题: this for "redux in rxjs"

发生了什么:

  • 我有两个组件,indextodos各有一个路径
  • 索引中的
  • 仅显示待办事项列表
  • 在待办事项中我可以删除并添加新的待办事项
  • 当我在不添加新待办事项或删除路线之间切换路线时,一切正常
  • 当我添加或删除待办事项时,它仍然有效,附加了新的待办事项,旧的被删除,console.log中的数据看起来不错
  • 当我在todo中添加或删除后转到不同的路线时,https://www.youtube.com/watch?v=xXau87UmqOs成为我调用的最后一个redux操作,例如 Object {type: "DELETE_TODO", id: 1} 而不是数组待办事项

这里是我在console.log中描述的内容(也可以在YouTube视频中看到)

---- index loaded ----
index.js:33 map in index: Object {todos: Array[3]}
index.js:35 resp in index: Object {todos: Array[3]}
index.js:38 ---- index destroyed ----
todos.js:31 ---- todos loaded ----
todos.js:33 map in todos: Object {todos: Array[3]}
todos.js:35 resp in todos: Object {todos: Array[3]}
todos.js:45 ---- todos destroyed ----
index.js:30 ---- index loaded ----
index.js:33 map in index: Object {todos: Array[3]}
index.js:35 resp in index: Object {todos: Array[3]}
index.js:38 ---- index destroyed ----
todos.js:31 ---- todos loaded ----
todos.js:33 map in todos: Object {todos: Array[3]}
todos.js:35 resp in todos: Object {todos: Array[3]}
NgStore.js:49 Object {type: "DELETE_TODO", id: 1}
todos.js:33 map in todos: Object {todos: Array[2]}
todos.js:35 resp in todos: Object {todos: Array[2]}
todos.js:45 ---- todos destroyed ----
index.js:30 ---- index loaded ----
index.js:33 map in index: Object {type: "DELETE_TODO", id: 1}
index.js:35 resp in index: Object {type: "DELETE_TODO", id: 1}

在路线发生变化时,有什么可能导致观察者发生变化?

这里是回购observable它使用了最新的alpha(46)

3 个答案:

答案 0 :(得分:3)

您错误地使用了RxJS API。要修复代码,您应该做以下两件事:

  1. 将初始状态设置为scan运算符。
  2. // services/NgStore.ts
    
    this._subject = new BehaviorSubject().scan(rootReducer, initialState);
    
    1. 更改switch语句中的条件以检查action是否为空(例如=== undefined):
    2. // reducers/todo.ts
      
      export const todos = (state = [], action) => {
        switch(action && action.type) {
          // ...
        }
      };
      

      PS 我不会删除那些不知道REDx已经在RxJS中实现的人的第一个答案。

答案 1 :(得分:1)

您不需要在redux中实施rxjs,因为它已在那里实施。 Observable::scan(accumulator, [seed])运算符与redux执行的操作完全相同。这是一个简化示例(请参阅this plunk):

// store.js
import BehaviorSubject from '@reactivex/rxjs/dist/cjs/subjects/BehaviorSubject';
import reducer from './reducer';
export default new BehaviorSubject().scan(reducer, 0)

// reducer.js
export default function(state, action) {
  switch (action && action.type) {
    case 'INCREMENT':
      return state + 1;
    case 'DECREMENT':
      return state - 1;
    default:
      return state;
  }
}

// app.js
import {Component} from 'angular2/angular2'
import store from './store';

@Component({
  selector: 'my-app',
  template: `
    <h2>{{ value }}</h2>
    <button (click)="increment()">Increment</button>
    <button (click)="decrement()">Decrement</button>
  `
})
export class App {
  constructor() {
    store.subscribe(value => this.value = value);
  }

  increment() { store.next({ type: 'INCREMENT' }) }
  decrement() { store.next({ type: 'DECREMENT' }) }
}

嗯,当然你可以重新发明轮子(至少只是为了好玩)。

答案 2 :(得分:1)

在黑暗中拍摄。路线变化是视野状态的变化。我敢打赌angular2会重新创建或更新你在路由器中配置的组件。你所描述的是:

  • 路线更改且型号无变化:确定
  • 路线更改和todo模型中的状态更改会给您错误的结果。

我在Angular的经历是nill,但从我读到的内容来看,我的直觉是:

  • 如果状态没有变化,路由器不会更新组件(不需要因为它们只依赖于没有改变的状态吗?)
  • 如果状态发生变化,则路由器会要求更新受影响的组件。因为你回到最后一次减少行动,并且你使用行为主体,我盲目地猜测你可能始终保持主题存活,并重新订阅路线变更,当你重新订阅时,你会回到最后价值(这是每个规格的行为主题)。

这是在黑暗中完全拍摄的,但你应该尝试在这些线上进行测试,至少要放弃这种可能性。