通过 putifAbsent 方法添加新项目后,我的地图没有更新

My map doesn't update after I add a new item through the putifAbsent method

我的地图没有添加任何新值。 这是我的提供商:

import 'package:flutter/material.dart';

import '../classes/transaction.dart';




class Transactions with ChangeNotifier {

  Map<String, Transaction> _userTransactions = {

   'ju': Transaction(amount: 45, date: DateTime.now(), title: 'socks', accountType: 'timr', notes: 'joa' , icon: Icon(Icons.today,), id: 'kololdcd', repeat: 'always')
  } ;
  
   
 Map<String, Transaction> get userTransactions {
   print (_userTransactions);
   return {..._userTransactions};
   
 }
 


   void addNewTransaction({String txTitle, double txAmount, DateTime chosenDate,
      String txAccountType, String txNotes, String txRepeat, Icon txIcon, String txId}) {
     
    
    if (txRepeat != 'Einmalig' && _userTransactions.containsKey(txId)){
    _userTransactions.update(txId, (existingItem) =>  Transaction(
      title: existingItem.title,
      amount: existingItem.amount,
      date: DateTime.now(),
      id: DateTime.now().toString(),
      accountType: existingItem.accountType,
      notes: existingItem.notes,
      repeat: existingItem.repeat,
      icon: existingItem.icon,
    ) );
    
    } else {
      _userTransactions.putIfAbsent(txId, ()=>  Transaction(
      title: txTitle,
      amount: txAmount,
      date: chosenDate,
      id: DateTime.now().toString(),
      accountType: txAccountType,
      notes: txNotes,
      repeat: txRepeat,
      icon: txIcon,
    ));

    }
    //final cant be changed anymore
    print (_userTransactions);
    notifyListeners();
    
  }
  
  
 


}
这是我的听众:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../providers/transactions.dart';

import 'package:intl/intl.dart';


class TransactionList extends StatelessWidget {
 

  @override
  Widget build(BuildContext context) {
   final transactionsData = Provider.of<Transactions>(context);
   final transactions = transactionsData.userTransactions;
   print (transactions);
 
    return transactionsData.userTransactions.isEmpty
        ? LayoutBuilder(builder: (ctx, constraints) {
            return Column(
              children: <Widget>[
                Text(
                  'Keine Transaktionen hinzugefügt. ',
                  style: Theme.of(context).textTheme.title,
                ),
                const SizedBox(height: 20),
                Container(
                  height: constraints.maxHeight * 0.6,
                
                ),
              ],
            );
          })
        : 
       
                 
                                     ListView.builder(
                 itemCount: transactions.length,     
                 itemBuilder:(context, i) {
                    String key = transactions.keys.elementAt(i);
                   return Card(
      color: Colors.transparent,
      elevation: 0,
      margin: const EdgeInsets.symmetric(
        vertical: 8,
        horizontal: 5,
      ),
      child: ListTile(
        leading: CircleAvatar(
          backgroundColor: Colors.transparent,
          radius: 30,
          child: Padding(
            padding: const EdgeInsets.all(6),
            child: FittedBox(
              child: Text('$${transactions[key].amount}'),
            ),
          ),
        ),
        title: Text(
          transactions[key].title,
          style: Theme.of(context).textTheme.title,
        ),
        subtitle: Text(
           DateFormat.yMMMd().format(transactions[key].date),
        ),
      
      ),

    );}
                  );
  }
}
我正在从另一个屏幕调用此提供程序方法:

void _submitData() {
    
    if (_amountController.text.isEmpty) {
      return;
    }

    final enteredTitle = _titleController.text;
    final enteredAmount = double.parse(_amountController.text);
    final enteredAccount = _accountController.text;
    final enteredNotes = _notesController.text;
    final enteredRepeat = _repeatController.text;
    final enteredIcon = Icon(MyIcon.paying);
    var uuid = Uuid(options: {});

    if (enteredTitle.isEmpty ||
        enteredAmount <= 0 ||
        _selectedDate == null ||
        enteredAccount.isEmpty ||
        enteredRepeat.isEmpty) {
      return; 
    } else {
      Transactions().addNewTransaction(
        txTitle: enteredTitle,
        txAmount: enteredAmount,
        chosenDate: _selectedDate,
        txAccountType: enteredAccount,
        txNotes: enteredNotes,
        txRepeat: enteredRepeat,
        txIcon: enteredIcon,
        txId: uuid.v1(options: {
          'node': [0x01, 0x23, 0x45, 0x67, 0x89, 0xab],
          'clockSeq': 0x1234,
          'mSecs': DateTime.now().millisecondsSinceEpoch,
          'nSecs': 5678
        }),
      );
    }
    Navigator.of(context).pop(context);
   
  }

如果我向地图添加新对,它会显示在 addTransactionMethod 中(打印语句为我提供新项目的值)。但是正如您在 userTransactions 的打印语句中看到的那样,我的地图 _userTransactions 没有采用新值,它只保留我硬编码的预定义值。

这是 Debugger Konsole(第一个打印语句来自 addTransaction 方法 - 第二个直接来自 userTransaction 映射:

I/flutter ( 5636): {ju: { kololdcd,socks,2020-02-14 22:33:09.616563, timr,joa,always,Icon(IconData(U+0E8DF)) ,45.0}, ho: { 2020-02-14 22:33:09.621559,Why not,2019-02-11 00:00:00.000, jes,cool,always,Icon(IconData(U+0E80D) ),78.0}}

I/flutter ( 5636): {ju: { kololdcd,socks,2020-02-14 22:32:14.896756, timr,joa,always,Icon(IconData(U+0E8DF)) ,45.0}}

如您所见,第二次打印中缺少第二项。

As you can see in the picture the new value sin't added to the map

我该如何解决这个问题?我只想向这个 _userTransactions 添加项目。

很想听听一些建议:)

问题是您的 class 小部件是 StatelessWidget。您无法更新 StatelessWidget,因为能够更新它意味着它具有可以更新的状态。对于您的方法,您必须将小部件更改为有状态:

class TransactionList extends StatefulWidget {
  TransactionList({Key key}) : super(key);

  @override
  State get createState => _TransactionListState();
}

class _TransactionListState extends State<TransactionList> {
  @override
  Widget build(BuildContext context) {
    ...
  }
}

另一种解决方案允许您将小部件保留为 StatelessWidget(无论如何更推荐),而不是直接调用 Provider.of,而是使用 Consumer自动将提供程序数据拉取到构建器方法。 Consumer 还将在您的事务对象更新时处理小部件的重建。

class TransactionList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<Transactions>(
      builder: (context, transactionsData, _) {
        ...
      },
    );
  }
}