通过 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, _) {
...
},
);
}
}
我的地图没有添加任何新值。 这是我的提供商:
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, _) {
...
},
);
}
}