读取从 stateNotifier 继承的类中的状态

时间:2021-05-14 03:50:00

标签: flutter dart riverpod

我正在尝试使用 flutter_riverpod 的 stateNotifierProvider 检索和删除 TodoList。 在下面的代码中,fetchTodoList 方法工作正常,但 deleteTodoList 方法不起作用。

界面

class TodoList extends ConsumerWidget {
  @override
  Widget build(BuildContext context, ScopedReader watch) {
    final todoAsyncValue = watch(todoFutureProvider);
    return Padding(
      padding: const EdgeInsets.all(8),
      child: todoAsyncValue.when(
        data: (todoList) => SingleChildScrollView(
          child: Scaffold(
            body: Column(
              children: _buildTodoList(todoList),
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: context.read(todoNotifierProvider.notifier).deleteTodoList(),
              child: const Icon(Icons.delete),
            ),
          ),
        ),
        loading: () => const Center(child: const CircularProgressIndicator()),
        error: (error, stack) => Text(error.toString()),
      ),
    );
  }
  _buildTodoList(){  // ......}
}

提供者和类

final todoNotifierProvider = StateNotifierProvider<TodoListStateNotifier, List<Todo>>((ref) {
    return TodoListStateNotifier();
});

final todoFutureProvider = FutureProvider<List<Todo>>((ref) async {
    final todo= ref.read(todoNotifierProvider.notifier);
    await todo.fetchTodoList();
    return ref.watch(todoNotifierProvider);
});


class TodoListStateNotifier extends StateNotifier<List<Todo>>{
  TodoListStateNotifier(): super([]);

  Future<void> fetchTodoList() async {
    final todoClient = TodoClient();
    state = await todoClient.fetchTodoList(); 
  }

  void deleteTodoList() {
    var list = <Todo>[];
    list = state.removeLast();
    state = list;
  }
}

显示以下错误消息。

<块引用>

“Todo”类型的值不能分配给类型变量 '列表'。

此外,如果我将代码转换为以下内容,则不会显示错误,但不会在 UI 中正确反映。

void deleteTodoList() {
    state.removeLast();
  }

我假设下面代码中定义的类型就是状态的类型,我错了吗?

class TodoListStateNotifier extends StateNotifier<List<Todo>>{

代码中的状态不是可以读取吗?

如果您知道更好的方法,请告诉我。

2 个答案:

答案 0 :(得分:1)

此处的 removeLast() 方法返回一个 Todo,正好是列表中的最后一个 Todo,这就是错误的原因

<块引用>

“Todo”类型的值不能分配给“List”类型的变量

因为您确实在尝试将 Todo 分配给 List。

 void deleteTodoList() {
    var list = <Todo>[];
    list = state.removeLast();
    state = list;
  }

现在使用第二个示例,这里您有效地删除了最后一个项目,但不发出新状态,因此 UI 不会重建。

void deleteTodoList() {
    state.removeLast();
  }

替代方案:

  1. 过滤并删除您想要的特定待办事项
    state = state.where((todo) => todo.id != target.id).toList()
  1. 不要将删除的值赋给变量
  void deleteTodoList() {
    var list = <Todo>[];
state.removeLast();
    list=state;
    state = list;
  }
  1. 使用 dart 级联运算符和展开运算符。

使用扩展运算符(...)复制列表,使用级联运算符为应用的方法不返回已删除的项目。

  void deleteTodoList() {
    state=[...state..removeLast()];
  }  

答案 1 :(得分:0)

每次UI重建时,都会调用该函数。 错误在这里:

import Foundation
import SwiftUI
import Firebase
    
class ViewModel: ObservableObject {
    
        @Published var array = [Any]()
    
        func getCount(){
    
            Firestore.firestore().collection("Posts").addSnapshotListener{ //then Posts has 2 documents
                (snap, err) in
    
                guard let docs = snap else{return}
    
                docs.documentChanges.forEach{ (doc) in
                    self.array.append(doc)
                }
            }
        }
}

你可以删除 onPressed: context.read(todoNotifierProvider.notifier).deleteTodoList(), 或者你可以写:

()