flutterアプリを開発し、ステートフルウィジェットをページとして作成します。
クラスを作成する状態クラスのthis
にビルド関数がアクセスできる2つの異なるファイルで、ビルド関数を他の状態変数および状態関数から分離したい:
PageClassState extend State<PageClass>{
string value = 'string value';
}
そして、それをPageClassState
this
変数にアクセスできる新しいクラスで拡張します。
PageClassView extend PageClassState{
@override
Widget Build(){
return(new Text(this.value))
}
}
しかし、PageClassState
では、クラスのビルドメソッドをオーバーライドする必要があるというエラーが表示されます。問題を修正し、MVVMデザインパターンをフラッターに実装するための提案はありますか?
ViewModelコードを、State
を拡張しない別のクラスに移動することをお勧めします。 ViewModelプラットフォームを独立させます。ウィジェットの状態は、viewModelのインスタンスを持ち、それと対話できます。
あなたはここに より詳細な例を見つけることができます
子ウィジェットがViewModelにアクセスする必要がある場合は、@RémiRousseletによって提案された継承ウィジェットを使用できます。私はすぐにこれを実装しました:
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);
ご不明な点がありましたらお知らせください:)
それは適切なアプローチではありません。 _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);
}
}
_
私はフラッター用の大規模なアプリケーションを維持するこのプラグインを使用しています。 mvvm_flutter
https://pub.dev/packages/mvvm_flutter
それは非常に軽くて使いやすいですいくつかの例を確認してください 。ビジネスロジックから離れたuiを維持するのは非常に簡単
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());