мы пытаемся разработать приложение флаттера и создаем виджет с отслеживанием состояния как страницу .
мы хотим отделить функцию сборки от другой переменной состояния и функции состояния в 2 разных файлах, которые функция сборки может получить доступ к this класса состояния
мы создаем класс:
PageClassState extend State<PageClass>{
string value = 'string value';
}
и расширите его новым классом, который может обращаться к переменной PageClassStatethis
мы пишем :
PageClassView extend PageClassState{
@override
Widget Build(){
return(new Text(this.value))
}
}
но в PageClassState мы получаем ошибку, говоря, что мы должны переопределить метод сборки в классе. есть ли какие-либо предложения по устранению проблемы и реализации шаблона проектирования MVVM во флаттере?
Это неправильный подход. Вы не должны разделять State<T> и это метод build.
Дело в том, что не расширяйте виджеты. Составьте их.
Правильный способ добиться чего-то подобного - использовать InheritedWidget. Они будут хранить ваши данные, но больше ничего не делать. И дети смогут запрашивать эти данные с помощью MyInherited.of(context).
Вы также можете создать builder. Что-то вроде :
typedef Widget MyStateBuilder(BuildContext context, MyStateState state);
class MyState extends StatefulWidget {
final MyStateState builder;
const MyState({this.builder}) : assert(builder != null);
@override
MyStateState createState() => new MyStateState();
}
class MyStateState extends State<MyState> {
String name;
@override
Widget build(BuildContext context) {
return widget.builder(context, this);
}
}
Я предлагаю переместить ваш код ViewModel в отдельный класс, не расширяющий State. Сохраняйте независимость платформы ViewModel.
Состояние ваших виджетов может иметь экземпляр viewModel и взаимодействовать с ним.
Вы можете найти более подробный пример здесь
Если дочерним виджетам требуется доступ к вашей модели просмотра, вы можете использовать унаследованный виджет, как это было предложено @ Rémi Rousselet. Я быстро реализовал это для вас:
class ViewModelProvider extends InheritedWidget {
final ViewModel viewModel;
ViewModelProvider({Key key, @required this.viewModel, Widget child})
: super(key: key, child: child);
@override
bool updateShouldNotify(InheritedWidget oldWidget) => true;
static ViewModel of(BuildContext context) =>
(context.inheritFromWidgetOfExactType(ViewModelProvider) as
ViewModelProvider).viewModel;
}
Дочерние виджеты могут получить ViewModel, вызвав
var viewModel = ViewModelProvider.of(context);
Дайте знать, если у вас появятся вопросы :)
Как мы можем обрабатывать приложение с более чем 50 ViewModels?
Пакет mvvm, реализация Flutter MVVM (Model-View-ViewModel).
import 'package:flutter/widgets.dart';
import 'package:mvvm/mvvm.dart';
import 'dart:async';
// ViewModel
class Demo1ViewModel extends ViewModel {
Demo1ViewModel() {
// define bindable property
propertyValue<String>(#time, initial: "");
// timer
start();
}
start() {
Timer.periodic(const Duration(seconds: 1), (_) {
var now = DateTime.now();
// call setValue
setValue<String>(#time, "${now.hour}:${now.minute}:${now.second}");
});
}
}
// View
class Demo1 extends View<Demo1ViewModel> {
Demo1() : super(Demo1ViewModel());
@override
Widget buildCore(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(vertical: 100),
padding: EdgeInsets.all(40),
// binding
child: $.watchFor(#time,
builder: $.builder1((t) =>
Text(t, textDirection: TextDirection.ltr))));
}
}
// run
void main() => runApp(Demo1());
Я использую этот плагин для поддержки крупномасштабного приложения для flutter.mvvm_flutter
https://pub.dev/packages/mvvm_flutter
это очень легкий и простой в использовании пример. его очень легко поддерживать пользовательский интерфейс вдали от бизнес-логики
вместо этого вы можете использовать модель с ограниченной областью видимости.