是否可以在 Mobx 中基于 DateTime.now 计算属性?

问题描述

我目前正在 Dart/Flutter 中尝试这个,但我认为这个概念在其他语言中是相同的。

考虑到 'expires' 收到一个代表 2 天后的日期,所以 'expired' 为真,并且应该在 2 天过后变为假。

@observable
DateTime expires;

@computed
bool get expired =>
      expires == null ||
      expires.difference(DateTime.Now()).inSeconds <= 0;

在运行应用程序时,此属性不会从 true 变为 false,但在我的单元测试中,它会改变,这就是为什么我不知道这是否可行。

单元测试供参考:

test('when expires pass its due date,it should trigger expired',() async {
  state.changeExpires(
    DateTime.Now().add(const Duration(seconds: 3)),);

  expect(
    state.hasTokenExpired,isFalse,reason:
        'because expires ${state.expires.toIso8601String()} should be in the interval expected to not be expired',);

  await Future.delayed(const Duration(seconds: 3));

  expect(
    state.hasTokenExpired,isTrue,reason:
        'because expired ${state.expires.toIso8601String()} has not expired',);
});

解决方法

对于 JS,有一个很好的 utils 库 mobx-utils,具有类似的功能 now(),它将更新所有观察者、反应等。

https://github.com/mobxjs/mobx-utils/blob/master/src/now.ts

也许你可以尝试为 Dart 实现它。

,

该解决方案可以通过流来实现。这是一个示例和 direct reference from mobx's flutter repository

class TimeStore = _TimeStoreBase with _$TimeStore;

abstract class _TimeStoreBase with Store {
  @observable
  DateTime expired = DateTime.now();
  @observable
  ObservableStream<DateTime> _time = Stream.periodic(Duration(seconds: 1))
      .map((_) => DateTime.now())
      .asObservable();

  @computed
  DateTime get now => _time.value ?? DateTime.now();

  @computed
  bool get expired => expires != null && expires.difference(now).inSeconds <= 0;
}