如何观察/订阅Aurelia商店中状态的变化?

时间:2018-07-12 16:02:00

标签: aurelia aurelia-binding aurelia-store

我在Aurelia商店的状态上有一个属性selectedOption,可以通过操作进行更改。我想观察/订阅对该状态在此属性上的任何更改。我的问题是BindingEngine中的订阅不起作用,因为每次更改状态时,都会创建该状态的新副本,因此该订阅不再起作用。

这是我的例子:

import { Disposable, BindingEngine, autoinject } from "aurelia-framework";
import { connectTo, dispatchify } from "aurelia-store";

@autoinject()
@connectTo()
export class Holiday {
    subscription: Disposable;
    state: any;

    constructor(private bindingEngine: BindingEngine) {
    }

    async updateState()
    {
        await dispatchify(changeSelectedOption)();
    }

    attached() {
        this.subscription = this.bindingEngine
            .propertyObserver(this.state, 'selectedOption')
            .subscribe((newValue, oldValue) => {
                console.log("something has changed!")
            });
    }
}

export class State {
    selectedOption: number = 0;
}

export const changeSelectedOption = (state: State) => {
    let updatedState = { ...state };
    updatedState.selectedOption++;
    return updatedState;
}

store.registerAction("changeSelectedOption", changeSelectedOption);

第一次,我的订阅将运行,并且控制台将记录“某些更改!”因为状态是同一个对象,但之后不会起作用。

我可以使用的另一个解决方案是拥有一个像这样的计算属性:

@computedFrom("state.selectedOption")
get selectedOptionChanged()
{
    return console.log("something has changed!");
}

这是一个hack,由于它没有绑定到HTML中的任何内容,因此永远不会被触发。

对于上下文,我想每次selectedOption属性更改时触发一次服务器调用。

我该怎么做才能从该州的物业接收所有更新?

1 个答案:

答案 0 :(得分:1)

这里的事情是商店可以观察到的状态是RxJS流。因此,随着connectTo的新“多重选择器”功能的出现,您可以创建两个绑定。通过实现名为selectorKey已更改的钩子,在示例selectedOptionChanged中,该属性的每次更改都将被调用。

@connectTo({
  selector: {
    state: (store) => store.state, // the complete state if you need
    selectedOption: (store) => store.state.pluck("selectedOption")
  }
})

class MyVM {
  ...
  selectedOptionChanged(newState, oldState) {
    // notification about new state
  }
}

除了通知store.state.pluck("selectedOption")等更改之外,您还可以尝试其他条件,代替添加distinctUntilChanged

updated docs中了解有关多重选择器的更多信息。


或者,如果您不想使用connectTo装饰器,只需使用state属性并创建另一个订阅