状态不更新列表中的flutter提供商

发布于 2025-01-19 20:18:37 字数 2471 浏览 2 评论 0原文

当我尝试更新列表时,我有2个问题,一个方法(下面的方法1)仅更新我通过的数据,其余数据为null,我有错误NULL检查运算符上使用的空值,因此我的窗口小部件在收听更改时会断开。另一个方法(下面的方法2)存在问题,因为我无法在列表中的何处更新数据,并且会得到错误非法分配到不可分配的表达式。缺少选择器,例如“ .Identifier”或“ [0]”。尝试添加选择器。,所以我不确定现在怎么办,我缺少什么。代码:

方法1:

List<ItemData>? _items = [];

List<ItemData>? get items => _items;

//Updates only the price and the other data in the state goes null
updatePrice(ItemData price) {
    _items![_items!.indexWhere((element) => element.itemId == price.itemId)] = price;
    notifyListeners();
  }

方法2:

List<ItemData>? _items = [];

List<ItemData>? get items => _items;

updatePrice(ItemData price) {
// I can't use this since I have to add an selector and I don't understand how
    _items!.firstWhere((element) => element.itemId == price.itemId) = price;
    notifyListeners();
  }

API调用:

 Future<ItemData> patchFee(
      currency, fee, itemId, transactionId) async {
    final response = await (ApiRequest(Method.PATCH, '/items',
        body: jsonEncode({
          "itemId": itemId,
          "transactionId": transactionId,
          "fees": [
            {
              "currency": currency,
              "type": "EXPENSE",
              "fee": fee,
              "description": "Item price",
            }
          ],
        })));
    Map<String, dynamic> jsonDecodedResponse =
        jsonDecode(utf8.decode(response!.bodyBytes));
    var list = jsonDecodedResponse['data']['fees'] as List;
    List<Fees> feesList = list.map((i) => Fees.fromJson(i)).toList();
    return ItemData(
      itemId: jsonDecodedResponse['data']['itemId'],
      transactionId: jsonDecodedResponse['data']['transactionId'],
      fees: feesList,
    );
  }

API调用的操作:

final itemStore = Provider.of<ItemStore>(context, listen: true);

...

TextButton(
            style: TextButton.styleFrom(
              textStyle: const TextStyle(fontSize: 20),
            ),
            onPressed: () async {
       final response = await patchFee(
      USD, 300, 123, 333);

      itemStore.updatePrice(response);
},
            child: const Text('Update Price'),
          ),

该补丁程序通过状态200,我以最终itemStore = provider.of&lt; itemStore&gt;(上下文,侦听:听: true);,所以我认为错误是我正在使用我的updatePrice(Price)方法对状态更新,但似乎无法弄清楚它是什么和原因。 预先感谢您的帮助。

When I try to update a list, I have 2 issues, one method (Method 1 below) only updates the data I'm passing and the rest of the data is null and I have the error Null check operator used on a null value, so my widget breaks when I listen to changes. The other method (Method 2 below) has issues because I can not specify where in the list should I update the data and I get an error Illegal assignment to non-assignable expression. Missing selector such as '.identifier' or '[0]'. Try adding a selector. So I'm not sure what do now, what am I missing. The code:

Method 1:

List<ItemData>? _items = [];

List<ItemData>? get items => _items;

//Updates only the price and the other data in the state goes null
updatePrice(ItemData price) {
    _items![_items!.indexWhere((element) => element.itemId == price.itemId)] = price;
    notifyListeners();
  }

Method 2:

List<ItemData>? _items = [];

List<ItemData>? get items => _items;

updatePrice(ItemData price) {
// I can't use this since I have to add an selector and I don't understand how
    _items!.firstWhere((element) => element.itemId == price.itemId) = price;
    notifyListeners();
  }

The API call:

 Future<ItemData> patchFee(
      currency, fee, itemId, transactionId) async {
    final response = await (ApiRequest(Method.PATCH, '/items',
        body: jsonEncode({
          "itemId": itemId,
          "transactionId": transactionId,
          "fees": [
            {
              "currency": currency,
              "type": "EXPENSE",
              "fee": fee,
              "description": "Item price",
            }
          ],
        })));
    Map<String, dynamic> jsonDecodedResponse =
        jsonDecode(utf8.decode(response!.bodyBytes));
    var list = jsonDecodedResponse['data']['fees'] as List;
    List<Fees> feesList = list.map((i) => Fees.fromJson(i)).toList();
    return ItemData(
      itemId: jsonDecodedResponse['data']['itemId'],
      transactionId: jsonDecodedResponse['data']['transactionId'],
      fees: feesList,
    );
  }

Action for the API call:

final itemStore = Provider.of<ItemStore>(context, listen: true);

...

TextButton(
            style: TextButton.styleFrom(
              textStyle: const TextStyle(fontSize: 20),
            ),
            onPressed: () async {
       final response = await patchFee(
      USD, 300, 123, 333);

      itemStore.updatePrice(response);
},
            child: const Text('Update Price'),
          ),

The patch goes through with status 200, I listen to the changes with final itemStore = Provider.of<ItemStore>(context, listen: true);, so I assume the error is that I'm updating the state with my updatePrice(price) method wrong, but can't seem to figure it out what and why.
Thanks you in advance for the help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

醉城メ夜风 2025-01-26 20:18:37

如果您不确定自己在做什么,请尝试使代码尽可能简单。

如果您不知道自己在做什么,那么使用 indexWherefirstWhere... 方法可能会很棘手,尤其是使用 null 安全性。

如果您想更新列表中的单个项目,您可以考虑使用简单的 for 循环,如下所示:

void updatePrice(ItemData price) {
  //Making a shallow copy of the original list
  var datasUpdate = _items?.toList();
  
  //Since the datasUpdate is a local var
  //we can null-check it to avoid using "!" everywhere
  if (datasUpdate != null) {
    for (int i = 0; i < datasUpdate.length; i++) {
      if (datasUpdate[i].id == price.id) {
        datasUpdate[i] = price;
        break;
      }
    }
    
    //Finally we update your initial List.
    //No need to use a shallow copy here
    _items = datasUpdate;
    notifyListeners();
  }
}

可以使用完整的工作示例 在此飞镖板上

If you're not sure about what you're doing, try to keep your code as simple as possible.

Playing with the indexWhere, firstWhere... methods can be tricky if you don't know what you're doing, even more with the null-safety.

If you wanna update a single item in your list, you could consider using a simple for loop like this :

void updatePrice(ItemData price) {
  //Making a shallow copy of the original list
  var datasUpdate = _items?.toList();
  
  //Since the datasUpdate is a local var
  //we can null-check it to avoid using "!" everywhere
  if (datasUpdate != null) {
    for (int i = 0; i < datasUpdate.length; i++) {
      if (datasUpdate[i].id == price.id) {
        datasUpdate[i] = price;
        break;
      }
    }
    
    //Finally we update your initial List.
    //No need to use a shallow copy here
    _items = datasUpdate;
    notifyListeners();
  }
}

A fully working example is available here on this dartpad

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文