Провайдер Flutter: как мне прослушать изменение поля класса внутри поля класса?
Учитывая следующую структуру классов Dart/Flutter:
import 'package:flutter/material.dart';
class A with ChangeNotifier {
B _element1;
B _element2;
B get element1 => _element1;
B get element2 => _element2;
set element1(B value) {
_element1 = value;
notifyListeners();
}
set element2(B value) {
_element2 = value;
notifyListeners();
}
}
class B {
String x;
String y;
}
Я пытаюсь прислушаться к смене A.element1.x
но проблема в том, что установщик класса B не может вызвать notifyListeners()
класса A, поэтому либо я слушаю A и не замечаю изменений, либо я слушаю B и теряю контекст для A.
Я использую пакет Provider в своем проекте Flutter. Но я не уверен, неправильно ли я понимаю концепцию пакета Provider или ChangeListeners. В любом случае я не могу найти элегантного решения.
Есть ли возможность перезаписать сеттер класса B из класса A? Очевидно, я мог бы реализовать функцию для каждого поля element1 и element2 (x,y). Но я думаю, это не лучший стиль кода.
1 ответ
Вот пример того, как вы можете использовать функции обратного вызова. Без обратного вызова A не позвонитnotifyListeners
и ваш Home
виджет не перестраивается. Вот короткое видео о том, чтоVoidCallback
это: https://www.youtube.com/watch?v=fWlPwj1Pp7U
Основная функция и простой Home
Посмотреть:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'a.dart';
void main() {
runApp(
ChangeNotifierProvider<A>(
create: (context) => A(),
child: MaterialApp(
home: Home(),
),
)
);
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<A>(
builder: (context, model, child) {
return Scaffold(
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('${model.element1.x}'),
RaisedButton(
child: Text("Set x of element1."),
onPressed: () {
Provider.of<A>(context, listen: false).element1.setX = 'Set to new value';
},
),
],
),
),
)
);
},
);
}
}
А затем класс A:
import 'package:flutter/material.dart';
import 'package:tryout/b.dart';
class A extends ChangeNotifier {
B _element1 = B();
B _element2 = B();
B get element1 => _element1;
B get element2 => _element2;
A() {
_element1.callback = () => notifyListeners();
_element2.callback = () => notifyListeners();
}
set element1(B value) {
_element1 = value;
_element1.callback = () => notifyListeners();
notifyListeners();
}
set element2(B value) {
_element2 = value;
_element2.callback = () => notifyListeners();
notifyListeners();
}
}
И класс B:
import 'package:flutter/cupertino.dart';
class B {
String x = "";
String y = "";
VoidCallback callback;
B({
this.callback
});
set setX(String newValueX) {
x = newValueX;
if(callback != null) callback();
}
void setY(String newValueY) {
y = newValueY;
if(callback != null) callback();
}
}