我正在尝试使用Provider
拆分窗口小部件的触发更新。
我正在使用最新的Flutter
版本。在应用程序中,我还使用context.select()
,context.watch()
和context.read()
。
现在是主要目标。我到底在说什么。所以我有一些通知者:
class ExpenseNotifier with ChangeNotifier {
List<Category> _selectedCategories = [];
Expense _currentExpense;
int _removeId;
Expense _editExpense;
}
现在,ExpenseNotifier
有几个消费者。发生变化时,所有使用者都将得到更新。除一种情况外:当_editExpense
更新时,只应更新一个使用者。问题是通知程序中已经存在类Expense
,因此所有连接到_currentExpense
的使用者都对_editExpense
更新有反应...
我现在正在使用选择器。像这样:
context.select<ExpenseNotifier, Expense>((notifier) => notifier.currentExpense);
但是由于某种原因,看起来小部件也对_editExpense
更新有反应...
那种情况的正确解决方案是什么?是否可以(不定义新类型)在ExpenseNotifier
内实现它?
可能类似的事情应该起作用:
class EditExpense {
final Expense expense;
EditExpense(this.expense);
}
因此在这种情况下,需要包装器类。如果我错了请纠正我
答案 0 :(得分:1)
我发现您的问题很有趣,因此我认为值得研究。我给出了一个一般性的答案,但我认为您会从中受益。
首先将方法添加到数据类中,这只会更新必填字段, 像这样:
class DataClass with ChangeNotifier {
String firstString = " ";
String secondString = " ";
void updateFirst(String newString) {
firstString = newString;
notifyListeners();
}
void updateSecond(String newString) {
secondString = newString;
notifyListeners();
}
}
现在是时候进行重构了,您必须制作两个具有自己的构建方法的类(或方法)(也可以定义两个方法并将BuildContext
传递给它们):
class StringOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("StringOne build method is called");
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Column(
children: [
Text(context.select((DataClass value) => value.firstString)),
Container(
height: 100,
width: 100,
child: TextField(
onChanged: (text) {
context.read<DataClass>().updateFirst(text);
},
),
)
],
)
],
);
}
}
和
class StringTwo extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("StringTwo build method is called");
return Column(
children: <Widget>[
Column(
children: [
Text(context.select((DataClass value) => value.secondString)),
Container(
height: 100,
width: 100,
child: TextField(
onChanged: (text) {
context.read<DataClass>().updateSecond(text);
},
),
),
],
)
],
);
}
}
最后,这些类在描述UI的其他类中:
class ProviderExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: [StringOne(), StringTwo()],
);
}
}
您可能会说它会增加冗长性,实际上,重构通常会使代码更冗长,但也使代码更清晰和易于维护。就您而言,这还将防止不必要的构建。
Console :
I/flutter ( 1469): StringTwo build method is called
I/flutter ( 1469): StringTwo build method is called
I/flutter ( 1469): StringTwo build method is called
I/flutter ( 1469): StringTwo build method is called
I/zygote64( 1469): Increasing code cache capacity to 1024KB
I/flutter ( 1469): StringOne build method is called
I/chatty ( 1469): uid=10140(com.example.stack_overflow) 1.ui identical 7 lines
I/flutter ( 1469): StringOne build method is called
I/flutter ( 1469): StringOne build method is called