gpt4 book ai didi

flutter Riverpod StateNotifierProvider : only watch changes for part of a model

转载 作者:行者123 更新时间:2023-12-05 02:04:25 27 4
gpt4 key购买 nike

我有这样一个模型:

class TimerModel {
const TimerModel(this.timeLeft, this.buttonState);
final String timeLeft;
final ButtonState buttonState;
}

enum ButtonState {
initial,
started,
paused,
finished,
}

这是 StateNotifierProvider:

class TimerNotifier extends StateNotifier<TimerModel> {
TimerNotifier() : super(_initialState);

static const int _initialDuration = 10;
static final _initialState = TimerModel(
_durationString(_initialDuration),
ButtonState.initial,
);

final Ticker _ticker = Ticker();
StreamSubscription<int> _tickerSubscription;

void start() {
if (state.buttonState == ButtonState.paused) {
_tickerSubscription?.resume();
state = TimerModel(state.timeLeft, ButtonState.started);
} else {
_tickerSubscription?.cancel();
_tickerSubscription =
_ticker.tick(ticks: _initialDuration).listen((duration) {
state = TimerModel(_durationString(duration), ButtonState.started);
});
_tickerSubscription.onDone(() {
state = TimerModel(state.timeLeft, ButtonState.finished);
});
state =
TimerModel(_durationString(_initialDuration), ButtonState.started);
}
}

static String _durationString(int duration) {
final String minutesStr =
((duration / 60) % 60).floor().toString().padLeft(2, '0');
final String secondsStr =
(duration % 60).floor().toString().padLeft(2, '0');
return '$minutesStr:$secondsStr';
}

void pause() {
_tickerSubscription?.pause();
state = TimerModel(state.timeLeft, ButtonState.paused);
}

void reset() {
_tickerSubscription?.cancel();
state = _initialState;
}

@override
void dispose() {
_tickerSubscription?.cancel();
super.dispose();
}
}

class Ticker {
Stream<int> tick({int ticks}) {
return Stream.periodic(Duration(seconds: 1), (x) => ticks - x - 1)
.take(ticks);
}
}

我可以像这样监听状态的所有变化:

final timerProvider = StateNotifierProvider<TimerNotifier>((ref) => TimerNotifier());

但是我想创建另一个只监听 ButtonState 变化的提供者。这不起作用:

final buttonProvider = StateProvider<ButtonState>((ref) {
return ref.watch(timerProvider.state).buttonState;
});

因为它仍然返回所有的状态变化。

这也行不通:

final buttonProvider = StateProvider<ButtonState>((ref) {
return ref.watch(timerProvider.state.buttonState);
});

因为 state 对象没有 buttonState 属性。

我如何只观察 buttonState 的变化?

最佳答案

使用 watch 会在监视状态发生变化时提供新状态。所以可以像这样分两部分解决问题:

final _buttonState = Provider<ButtonState>((ref) {
return ref.watch(timerProvider.state).buttonState;
});

每次 timerProvider.state 更改时,使用此提供程序都会导致重建。但是,诀窍是执行以下操作:

final buttonProvider = Provider<ButtonState>((ref) {
return ref.watch(_buttonState);
});

由于 _buttonState 对于大多数 timerProvider.state 更改都是相同的,所以观看 _buttonState 只会在 _buttonState 时导致重建 实际上改变了。

感谢this post用于显示答案。该帖子还表明很快就会有一个简化的语法:

final buttonState = ref.watch(timerProvider.state.select((state) => state.buttonState));

关于 flutter Riverpod StateNotifierProvider : only watch changes for part of a model,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64346019/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com