【问题标题】:Move from ChangeNotifier to ValueNotifier in Flutter with Provider在 Flutter 中使用 Provider 从 ChangeNotifier 转移到 ValueNotifier
【发布时间】:2020-06-28 01:40:19
【问题描述】:

我目前正在使用 Flutter 中的一个应用程序,我正在使用 Provider 作为状态管理,我正在使用 <Data>ChangeNotifierProvider 数据是 class Data extends ChangeNotifier 的一个类,其中包含我的整个应用程序的大量信息,我使用方法修改我的数据,然后使用notifyListeners(); 使用两个变量更新我的应用程序的多个位置的数据:

final Data provListen =Provider.of<Data>(context);
final Data provNoListen = Provider.of<Data>(context, listen: false);

然后我选择何时使用provListenprovNoListen,具体取决于父小部件是否需要更新。

我最近读到使用ValueNotifier 而不是ChangeNotifier 是更好的做法,因为您不必为ValueNotifier 设置参数listen: false,但在ValueNotifier 的描述中它说:

保存单个值的 ChangeNotifier。

所以问题是,我可以使用ValueNotifier 并将整个类作为类型传递吗?还是我应该继续使用ChangeNotifier 作为我的解决方案?

我将粘贴我的数据类以供参考,但我不知道我的问题是否需要它:

这是我的课:

class Data extends ChangeNotifier{
  FirebaseUser loggedInUser;
  FirebaseCaller firebaseCaller;
  List<NeighborDataModel> neighborhoodData = [];
  List<NeighborDataModel> searchDisplayData = [];
  List<NeighborDataModel> unchangedNeighborhoodData = [];
  List<PaymentDataModel> neighborPayments = [];
  List<Color> neighborColor = [];
  NeighborDataModel neighbor;
  PaymentDataModel payment;
  double currentOpacity = 1;
  bool absorbingTextFields = false;
  String email;
  String password;
  String recoverPasswordFeedback = '';
  String keyFeedback = '';
  TextEditingController nameController = new TextEditingController();
  TextEditingController addressController = new TextEditingController();
  TextEditingController emailController = new TextEditingController();
  TextEditingController phoneController = new TextEditingController();
  TextEditingController dateController = new TextEditingController();
  TextEditingController keysController = new TextEditingController();
  Map neighborDisplaySettings = {
    'edit_icon_color': Colors.white,
    'icon_color': Colors.grey,
    'edit_data': false,
    'button_bar_visible': true,
  };

  Map filterSelection = {
    'inactive': true,
    'active': false,
    'all_neighbors': false,
  };

  /// Creates an instance of the Firebase User
  void firebaseUser(FirebaseUser loginUser) {
    loggedInUser = loginUser;
    notifyListeners();
  }

  /// Creates an instance of the Firebase Caller
  void firebaseCall(FirebaseCaller firebaseCall) {
    firebaseCaller = firebaseCall;
    notifyListeners();
  }

  /// Updates User Email
  void saveEmail(String newEmail) {
    email = newEmail;
    notifyListeners();
  }

  /// Updates User Password
  void savePassword(String newPassword) {
    password = newPassword;
    notifyListeners();
  }

  /// String to Diagnose Password Recovery
  void updatePasswordFeedback(String message) {
    recoverPasswordFeedback = message;
    notifyListeners();
  }

  /// String to Diagnose Key Adding
  void updateKeyFeedback(String message) {
    keyFeedback = message;
    notifyListeners();
  }

  /// Changes the filter selection
  void updateFilterSelection(Map newFilter) {
    filterSelection = newFilter;
    notifyListeners();
  }

  /// Updates all the Neighbors and the filtered Neighbors per search
  void updateNeighborsData(neighborsData) async {
    neighborhoodData = [];
    searchDisplayData = [];
    unchangedNeighborhoodData = [];
    unchangedNeighborhoodData.addAll(neighborsData);

    if (filterSelection['all_neighbors']) {
      neighborhoodData.addAll(neighborsData);
      searchDisplayData.addAll(neighborsData);
    } else if (filterSelection['active'] && filterSelection['inactive']) {
      for (NeighborDataModel thisNeighbor in neighborsData) {
        if (thisNeighbor.debt > 0 || thisNeighbor.debt == 0) {
          neighborhoodData.add(thisNeighbor);
          searchDisplayData.add(thisNeighbor);
        }
      }
    } else if (filterSelection['active']) {
      for (NeighborDataModel thisNeighbor in neighborsData) {
        if (thisNeighbor.debt == 0) {
          neighborhoodData.add(thisNeighbor);
          searchDisplayData.add(thisNeighbor);
        }
      }
    } else if (filterSelection['inactive']) {
      for (NeighborDataModel thisNeighbor in neighborsData) {
        if (thisNeighbor.debt > 0) {
          neighborhoodData.add(thisNeighbor);
          searchDisplayData.add(thisNeighbor);
        }
      }
    }
    Future(()=>notifyListeners());
  }

  /// Updates all the Payments for an specific Neighbor
  void updateNeighborsPayments(payments) async {
    neighborPayments.addAll(payments);
    notifyListeners();
  }

  /// Updates the Neighbor(s) of the search
  void updateSearcherData(newData) {
    searchDisplayData.clear();

    if (newData.isNotEmpty) {
      searchDisplayData.addAll(newData);
    } else {
      searchDisplayData.addAll(neighborhoodData);
    }
    notifyListeners();
  }

  /// Gets the Data of the Current Selected User
  void updateCurrentUser(NeighborDataModel currentNeighbor) {
    neighbor = currentNeighbor;
    nameController.text = '${neighbor.name} ${neighbor.lastName}';
    addressController.text = '${neighbor.streetName} ${neighbor.houseNumber}';
    emailController.text = neighbor.email;
    phoneController.text = neighbor.phone;
    dateController.text = neighbor.lastPayment['date'];
    Future(()=>notifyListeners());
  }
  /// Update Color gradient for Current Selected User
  void updateGradientForCurrentUser (List<Color> gradientList){
    neighborColor = gradientList;
    Future(()=> notifyListeners());
  }

  void updateCurrentPayment(PaymentDataModel currentPayment){
    payment = currentPayment;
    Future(()=>notifyListeners());
  }

  /// Greys out or Back to Normal the Login Screen
  void changeOpacityLogin(double newOpacity) {
    currentOpacity = newOpacity;
    notifyListeners();
  }

  /// Blocks the Text Fields for Password Recovery
  void textFieldPermission(bool newPermission) {
    absorbingTextFields = newPermission;
    notifyListeners();
  }

  /// Changes the text of each controller depending on the controllerName
  void editNeighborTextControllers(String newText, String controllerName) {
    switch (controllerName) {
      case 'nameController':
        nameController.text = newText;
        notifyListeners();
        break;
      case 'addressController':
        addressController.text = newText;
        notifyListeners();
        break;
      case 'emailController':
        emailController.text = newText;
        notifyListeners();
        break;
      case 'phoneController':
        phoneController.text = newText;
        notifyListeners();
        break;
      case 'keysController':
        keysController.text = newText;
        notifyListeners();
        break;
      case 'dateController':
        dateController.text = newText;
        notifyListeners();
        break;
    }
  }

  /// Change to Editing Mode
  void changeToEditMode(bool activate, context) {
    if (activate) {
      neighborDisplaySettings = {
        'edit_icon_color': Theme.of(context).indicatorColor,
        'icon_color': Theme.of(context).indicatorColor,
        'edit_data': true,
        'button_bar_visible': false,
      };
    } else {
      neighborDisplaySettings = {
        'edit_icon_color': Colors.white,
        'icon_color': Colors.grey,
        'edit_data': false,
        'button_bar_visible': true,
      };
    }
    notifyListeners();
  }
}

提前致谢!

【问题讨论】:

  • 这个想法是,将通知程序的所有属性提取到一个单独的类中,并将其用作“值”。
  • 嗨,雷米,谢谢你的回答,顺便说一句,提供者很棒,我对这个概念有点新,你能用我的代码分享一个例子吗?提前致谢!
  • @MiguelChavez,你去过this blog吗?它展示了ValueNotifier ChangeNotifier 的区别。

标签: flutter dart flutter-provider


【解决方案1】:

ValueNotifierChangeNotifier 具有相似的功能。如果您只需要在数据更改时简单地重建小部件,则可以使用 ValueNotifier。另一方面,ChangeNotifier 通过notifyListeners() 提供精细控制。如果其中一个适合您,则可以保持原样,只要它适合您的用例。

【讨论】:

    猜你喜欢
    • 2020-12-30
    • 1970-01-01
    • 2022-08-14
    • 2020-11-03
    • 2021-01-29
    • 2020-02-29
    • 2020-12-17
    • 2021-07-20
    • 1970-01-01
    相关资源
    最近更新 更多