首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >发出新状态时不重建Cubit

发出新状态时不重建Cubit
EN

Stack Overflow用户
提问于 2020-12-01 20:23:49
回答 2查看 1.2K关注 0票数 1

每当我调用toggleLocked事件时,BlocBuilder都不会重新构建小部件。

我在互联网上看了很多,找到了这样的解释:https://stackoverflow.com/a/60869187/3290471我认为我错误地使用了equatable包,这导致了BlocBuilder认为什么都没有改变(而is已经改变了)。

我已经阅读了来自Bloc libray的常见问题解答,并且提供的三个解决方案(支持equatable /不重用相同的状态/使用fromList)似乎不能解决问题。

我的Cubit:

代码语言:javascript
复制
class LockCubit extends Cubit<LockState> {
  LockCubit({@required this.repository})
      : assert(repository != null),
        super(LockInitial());

  final LocksRepository repository;

  Future<void> fetch() async {
    try {
      final locks = await repository.fetchLocks();
      emit(LocksDisplayed().copyWith(locks));
    } on Exception {
      emit(LockError());
    }
  }

  Future<void> toggleLocked(int id) async {
    try {
      final locks = await repository.toggleLocked(id);
      emit(LocksDisplayed().copyWith(List.from(locks)));
    } on Exception {
      emit(LockError());
    }
  }
}

我的状态:

代码语言:javascript
复制
abstract class LockState extends Equatable {
  const LockState();

  @override
  List<Object> get props => [];
}

class LockInitial extends LockState {
  @override
  String toString() => 'LocksUninitialized';
}

class LockError extends LockState {
  @override
  String toString() => 'LockError';
}

class LocksDisplayed extends LockState {
  final List<Lock> locks;

  const LocksDisplayed([this.locks = const []]);

  LocksDisplayed copyWith(locks) => LocksDisplayed(locks ?? this.locks);

  @override
  List<Object> get props => [locks];

  @override
  String toString() => 'LocksDisplayed { locks: $locks }';
}

我的模型:

代码语言:javascript
复制
class Lock extends Equatable {
  Lock({this.id, this.name, this.locked, this.displayed});

  final int id;
  final String name;
  final bool locked;
  final bool displayed;

  @override
  String toString() =>
      'Lock { id: $id name: $name locked: $locked displayed: $displayed }';

  Lock copyWith({id, name, locked, displayed}) => Lock(
      id: id ?? this.id,
      name: name ?? this.name,
      locked: locked ?? this.locked,
      displayed: displayed ?? this.displayed);

  @override
  List<Object> get props => [id, name, locked, displayed];
}

我的存储库:

代码语言:javascript
复制
class LocksRepository {
  List<Lock> locks = [];

  Future<List<Lock>> fetchLocks() async {
    // This is a temporary implementation
    // In the future the data should be fetched from a provider

    locks = [
      new Lock(
        id: 0,
        name: 'Voordeur',
        locked: false,
      ),
      new Lock(
        id: 1,
        name: 'Achterdeur',
        locked: false,
      )
    ];

    return locks;
  }

  Future<List<Lock>> toggleLocked(int id) async {
    // This is a temporary implementation
    // In the future a request to change a lock should be made and then the specific lock should be retrieved back and edited.

    locks[id] = locks[id].copyWith(locked: !locks[id].locked);

    return locks;
  }
}

我正在使用以下触发器更改状态:

代码语言:javascript
复制
context.read<LockCubit>().toggleLocked(focusedIndex);

我像这样使用BlocBuilder来构建状态:

代码语言:javascript
复制
BlocBuilder<LockCubit, LockState>(builder: (context, state) {
      print('State Changed');

      if (state is LockInitial) {
        return Text('lockInitial');
      }

      if (state is LocksDisplayed) {
        return Swiper(
            itemBuilder: (BuildContext context, int index) {
              return Column(
                children: [
                  Text(state.locks[index].name),
                  Text(state.locks[index].locked.toString())
                ],
              );
            },
            onIndexChanged: onIndexChanged,
            loop: true,
            itemCount: state.locks.length);
      }

      if (state is LockError) {
        return Text('lockError');
      }

      return Container();
    });

所有的帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

发布于 2020-12-15 18:41:41

你能查一下BlocProvider吗?我也有同样的问题。如果此阻塞位于materialApp内部,则必须传递BlocProvider.value,而不是在小部件中创建。

票数 2
EN

Stack Overflow用户

发布于 2020-12-01 21:06:18

如果这能行得通,我有点困惑。但是对于bloc,您将使用事件,而不是cubit (即使事件是基于cubit的)。

因此,首先我将使用标准模式:使用mapEventToState进行状态事件阻塞

然后,我在你的代码中也看不到的是,如果你切换你的锁,它在伪代码中会是这样的

代码语言:javascript
复制
if (event is toggleLock) {
  yield lockInProgress();
  toggleLock();
  yield locksDisplayed;
}

这样,您的状态总是从locksDisplayed更改为lockInProgress,再更改为locksDisplayed -正如您在上面的链接中所看到的那样

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65090423

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档