ããã¯ãFlutter Architectureã«é¢ããç§ã®ã·ãªãŒãºã®ç¬¬2éšã§ãã
ã¹ããªãŒã ã¯RxVMSã®äž»èŠãªæ§æèŠçŽ ã§ãã ããã®ã©ã€ãã©ãªãæäœããã«ã¯ãããã®ç解ã絶察ã«å¿
èŠã§ããããããã®æçš¿ã§ã¯ã¹ããªãŒã ã«ã€ããŠè©³ãã説æããŸãã
ãã®æçš¿ã«Rxãå«ãããšé·ãããããšãå€æããããã2ã€ã®éšåã«åå²ããŸããã
æµããŠ
ãããŒãç¹ã«Rxã¯è€éãããŠç解ã§ãããçµæãšããŠäœ¿çšã§ããªããšããã³ã¡ã³ããããããèªã¿ãŸããã
ç§ã¯èªåãRxã®ç¬¬äžäººè
ãšã¯èããŠããªãããšãç¥ã£ãŠã»ããã 圌ã®åããã¹ãŠæŽ»çšããã®ã¯ç°¡åã§ã¯ãããŸãããç§ã¯å匷ãç¶ããŠããããšãèªããŸãã ãã ããæåãã1ã€ã®ééããä¿®æ£ããŸãããã ã¹ã¬ãããšãã®ãã¯ãããžãŒã䜿çšããŠå€ãã®ã¡ãªãããåŸãã«ã¯ãRxãŠã£ã¶ãŒãã§ããå¿
èŠã¯ãããŸãã ã ãããŒãæãã¢ã¯ã»ã¹ããããæ¹æ³ã§èª¬æããããã«ããããåªåãããŸãã
ã¹ããªãŒã ãšã¯äœã§ããïŒ
ç§ã®æèŠã§ã¯ãã¹ã¬ããã«æãè¿ãã®ã¯ã³ã³ãã¢ãã«ãã§ãã ããªãã¯ããã®äžç«¯ã«äœãã眮ãããšãã§ãããã®ãäœããã¯èªåçã«ããäžæ¹ã«è»¢éãããŸãã ç©çãã€ãã©ã€ã³ãšã¯ç°ãªããã¹ã¬ããã¯ããŒã¿ãªããžã§ã¯ããæäœããæåããèªåçã«è»¢éããŸãããã©ãã§ïŒ å®éã®ãã€ãã©ã€ã³ã®ããã«ãããäžæ¹ã®ç«¯ã§ããŒã¿ããã£ãããããã®ããªãå Žåããããã¯åã«ãèœã¡ããŠæ¶ããŸãïŒãã¡ãããããã¯Dart Streamsã«ã¯ãŸã£ããåœãŠã¯ãŸããŸãããããã®ããã«ã¹ããªãŒã ãåŠçããã®ãæåã§ãïŒ ã
ããŒã¿ã®æ倱ãé²ãããã«ãã¹ããªãŒã åºåã«ããã©ããããèšå®ã§ããŸãã ããã«ãããããŒã¿ãªããžã§ã¯ããã¹ããªãŒã ã®æåŸã«å°éãããã³ã«ãããŒã¿ããã£ããã£ããå¿
èŠãªæäœãå®è¡ã§ããŸãã
èŠããŠãããŠãã ããïŒ
- ãã©ãããèšå®ãããŠããªãå ŽåãããŒã¿ã¯åçŽã«æ°žä¹
ã«æ¶ããåã³ååŸããæ¹æ³ã¯ãããŸããïŒåã³ãDart Streamsã§ã¯æ£ç¢ºã§ã¯ãããŸãããããããè£
ãæ¹ãè¯ãã§ãããïŒ
- ã¹ããªãŒã ã«ããŒã¿ãéä¿¡ããåŸãããã°ã©ã ãäžæåæ¢ããŠçµäºãããŸã§åŸ
ã€å¿
èŠã¯ãããŸããããããã¯ãã¹ãŠããã¯ã°ã©ãŠã³ãã§è¡ãããŸãã
- ãã©ããã¯ãã€ã§ãããŒã¿ãåä¿¡ã§ããŸããéä¿¡çŽåŸã¯å¿
èŠãããŸããïŒãã ããã¹ããªãŒã ã¯å®éã«ã¯éåžžã«é«éã§ãïŒã ã³ã³ãã¢ãã«ãã®ç§»åé床ãé·ããããããªãããšãæ³åããŠãã ããã ã€ãŸããã¹ããªãŒã ã«äœããé
眮ããããšã¯ãããäžæ¹ã®ç«¯ã®èŠçŽ ã«å¯Ÿããåå¿ãšã¯å®å
šã«åé¢ãããŸãã ãã©ããã¯æ©èœããã¢ã€ãã ãå°çãããšãã£ããããŸãã ïŒããã¯ãFlutterããŠã£ãžã§ãããæŽæ°ãããªã¢ã¯ãã£ããªæ¹æ³ãšããŸãé©åããããšãæ¢ã«ãåããããããŸããïŒ
- äœæ¥ãéå§ããæåã®é
ç®ã衚瀺ãããããªãåã«ãã©ãããèšå®ã§ããŸã
- ãããŒã¯FIFOã®åçã«åºã¥ããŠæ©èœããŸãã ããŒã¿ã¯åžžã«ãã¹ããªãŒã ã«é
眮ãããé çªã«ãªããŸãã
Rxãšã¯äœã§ããïŒ
Reactive Extensionsã®ç¥ã§ããRxã¯ãã¹ããã€ãã¹ããªãŒã ã§ãã ããã¯ãMicrosoftããŒã ã.Netãã¬ãŒã ã¯ãŒã¯çšã«èæ¡ããStreamsã«éåžžã«ãã䌌ãæŠå¿µã§ãã .Netã«ã¯æ¢ã«ãã¡ã€ã«I / Oã«äœ¿çšãããStreamã¿ã€ãããããããRxã¹ããªãŒã ã«Observablesãšããååãä»ããééããããŒã¿ãæäœããå€ãã®é¢æ°ãäœæããŸããã Dartã«ã¯ãèšèªä»æ§ã«çµã¿èŸŒãŸããStreamsããããŸããããã¯ããã¹ãŠã§ã¯ãããŸããããã»ãšãã©ã®æ©èœãæ¢ã«æäŸããŠããŸãã ããããRxDartããã±ãŒãžãéçºãããçç±ã§ãã Dart Streamsã«åºã¥ããŠããŸãããæ©èœãæ¡åŒµããŠããŸãã ãã®ã·ãªãŒãºã®æ¬¡ã®ããŒãã§ã¯ãRxãšRxDartã«ã€ããŠèª¬æããŸãã
ããã€ãã®çšèª
Dart StreamsãšRxã¯æãããã«èŠãããããããªãçšèªã䜿çšããŠããã®ã§ãããã«ç¿»èš³ããããŸãã æåã«Dartãšããçšèªã次ã«Rxãšããçšèªãæ¥ãŸãã
- ã¹ããªãŒã /芳枬å¯èœ ã ããã¯ãåè¿°ã®ããã€ãã©ã€ã³ãã§ãã ã¹ããªãŒã ã¯Observableã«å€æã§ããStreamãäºæ³ãããå Žæãªãã©ãã§ãObservableãå²ãåœãŠãããšãã§ããŸãã ã ããã説æã®éçšã§ãããã®çšèªãæ··ããŠãæ··ä¹±ããªãã§ãã ãã
- listen / subscribe- ãªã¹ããŒãã©ãããèšå®ããŸã
- StreamController / Subject ã³ã³ãã¢ãã«ãã®ãå·ŠåŽãã¯ãããŒã¿ãã¹ããªãŒã ã«é
眮ããå Žæã§ãã ããããã£ãšç¹æ§ã¯ãããã«ç°ãªããŸãããåãç®çãæãããŸãã
- ã¢ã€ãã /ããŒã¿ã®çºè¡ ã ããã€ãã©ã€ã³ãã®åºå£ã«ããŒã¿ã衚瀺ãããç¬é
ã¹ããªãŒã äœæ
ãããã¯ã®åŠç¿ãç¶ããå Žåã¯ã ãã®ãããžã§ã¯ãã®ã¯ããŒã³ãäœæããŠãã ããã Dart / Flutterãã¹ãã·ã¹ãã ã䜿çšããŸãã
ã¹ããªãŒã ãäœæããã«ã¯ã StreamControllerãäœæããŸã
var controller = new StreamController<String>(); controller.add("Item1");
StreamControllerã®äœææã«æž¡ããããã³ãã¬ãŒãã¿ã€ãïŒãã®å Žåã¯StringïŒã¯ãã¹ããªãŒã ã«éä¿¡ã§ãããªããžã§ã¯ãã®ã¿ã€ãã決å®ããŸãã ã©ã®ã¿ã€ãã§ãããŸããŸããïŒ å¿
èŠã«å¿ããŠStreamController<List<MyObject>>()
ãäœæã§ããŸããã¹ããªãŒã ã¯åäžã®ãªããžã§ã¯ãã§ã¯ãªãã·ãŒãå
šäœã転éããŸãã
ãã©ããèšå®
æå®ããããã¹ããå®è¡ããå Žåãã¹ããªãŒã ã®åºåã§è¡ããã£ãããããªãã£ããããäœã衚瀺ã§ããŸããã§ããã 次ã«ããã©ãããèšå®ããŸãã
var controller = new StreamController<String>(); controller.stream.listen((item) => print(item));
ããã§ããã©ããã¯.listen()
ã¡ãœããã䜿çšããŠèšå®ãããŸãã ã¬ã³ãŒãã¯controller.stream.listen
ããã«èŠããŸããã60幎代ã®ã¢ã«ãã ã®ããã«åŸæ¹ã«ã¹ã¯ããŒã«ãããšãããã®ã³ã³ãããŒã©ãŒã®ã¹ããªãŒã ãèŽãããšããçã®æå³ã衚瀺ãããŸãã
åä¿¡ããŒã¿ãäœããã®æ¹æ³ã§æäœããã«ã¯ãç¹å®ã®é¢æ°ã.listen()
ã¡ãœããã«æž¡ãå¿
èŠããããŸãã ãã®é¢æ°ã¯ãStreamControllerã®äœææã«æå®ãããã¿ã€ãã®ãã©ã¡ãŒã¿ãŒïŒãã®å Žåã¯StringïŒãåãå
¥ããå¿
èŠããããŸãã
äžèšã®ã³ãŒããå®è¡ãããšã衚瀺ãããŸã
Item1 Item2 Item3
ç§ã®æèŠã§ã¯ãStreamsã®æ°èŠåå
¥è
ã«ãšã£ãŠæ倧ã®åé¡ã¯ãæåã®èŠçŽ ãã¹ããªãŒã ã«é
眮ããããã£ãšåã«ãæŸåºãããèŠçŽ ã®åå¿ã決å®ã§ãããã®åå¿ã®åŒã³åºããããªã¬ãŒã§ããããšã§ãã
ãªã¹ãã³ã°ãçµäº
äžèšã®ã³ãŒãã§ã¯ãå°ãããªãããéèŠãªéšåãæ¬ èœããŠããŸãã listen()
ã¯StreamSubscription
ã¹ããªãŒã ãµãã¹ã¯ãªãã·ã§ã³ãªããžã§ã¯ããè¿ããŸãã 圌ã®.cancel()
ã¡ãœãããåŒã³åºããšããµãã¹ã¯ãªãã·ã§ã³ãçµäºãããªãœãŒã¹ã解æŸããããªã¹ãã³ã°æ©èœãäžèŠã«ãªã£ãåŸã®åŒã³åºããé²æ¢ãããŸãã
var controller = new StreamController<String>(); StreamSubscription subscription = controller.stream.listen((item) => print(item));
ãªã¹ããŒã®è©³çŽ°
listen()
ã®é¢æ°ã¯ãã©ã ããŸãã¯åçŽãªé¢æ°ã®ããããã§ãã
void myPrint(String message) { print(message); } StreamSubscription subscription = controller.stream.listen((item) => print(item));
éèŠãªæ³šæïŒã»ãšãã©ã®Dartã¹ããªãŒã ã§ã¯ã1åéãã®ãµãã¹ã¯ãªãã·ã§ã³ããèš±å¯ãããŠããŸãããã€ãŸãããµãã¹ã¯ãªãã·ã§ã³ã®å®äºåŸã«åãµãã¹ã¯ã©ã€ãããããšã¯ã§ããŸãããããã¯äŸå€ãã¹ããŒããŸãã ããã¯ãä»ã®Rxå®è£
ãšã®éãã§ãã
listen()
ã®å®å
šãªçœ²åã¯æ¬¡ã®ããã«ãªããŸãã
StreamSubscription<T> listen(void onData(T event), {Function onError, void onDone(), bool cancelOnError});
ããã¯ãéä¿¡ãããããŒã¿ã«å¯ŸããŠ1ã€ã®ãã³ãã©ãŒãæž¡ãã ãã§ãªããè€æ°ã®ããšãã§ããããšãæå³ããŸãã ãŸãããšã©ãŒã®ãã³ãã©ãŒãšãã³ã³ãããŒã©ãŒåŽã§ã¹ããªãŒã ãéãããã³ãã©ãŒïŒ onDone
ïŒãæã€ããšãã§ããŸãã Streamå
ããonError()
ããäŸå€ã¯ã æå®ããå Žåã«onError()
ãonError()
ãŸãã ãã以å€ã®å ŽåãäŸå€ã¯åã«é£²ã¿èŸŒãŸããäœããããŸããããªãã£ãããšã¯æ±ºããŠããããŸããã
ãã©ãã¿ãŒã¹ã¬ããã®äŸ
次ã®ç« ã®ç解ã容æã«ããããã«ãå¥ã®ãªããžããªãã©ã³ããäœæããŸããã
圌女ãã¯ããŒã³ããŠãã ãã
æåã®äŸãšããŠãæ°ããFlutterãããžã§ã¯ããäœæãããšãã«ååŸããæåãªã«ãŠã³ã¿ãŒã¢ããªã±ãŒã·ã§ã³ãåãäžããå°ãåç·šæããŸããã ã¢ããªã±ãŒã·ã§ã³ã®ç¶æ
ãä¿åããã¢ãã«ã¯ã©ã¹ãè¿œå ããŸãããããã¯åºæ¬çã«ã«ãŠã³ã¿ãŒå€ã§ãã
class Model { int _counter = 0; StreamController _streamController = new StreamController<int>(); Stream<int> get counterUpdates => _streamController.stream; void incrementCounter() { _counter++; _streamController.add(_counter); } }
ããã§ã¯ãéåžžã«å
žåçãªãã³ãã¬ãŒããèŠãããšãã§ããŸããStreamControllerå
šäœãå
¬éãã代ããã«ãåã«Streamããããã£ãå
¬éããŸãã
ã¢ãã«ãUIã§äœ¿çšã§ããããã«ããããã«ãInheritedWidgetãŸãã¯ServiceLocatorãå
¥åããããªããããAppãªããžã§ã¯ãã®éçãã£ãŒã«ãã«ããŸããã ç°¡åãªäŸã§ã¯ãããã§ããŸããããŸããããã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯è¡ããŸããïŒ
main.dart
è¿œå ãmain.dart
ã
class _MyHomePageState extends State<MyHomePage> { int _counter = 0; StreamSubscription streamSubscription; @override void initState() { streamSubscription = MyApp.model.counterUpdates.listen((newVal) => setState(() { _counter = newVal; })); super.initState(); }
initState()
ãªã¹ããŒãèšå®initState()
é©ããå Žæã§ããããŒãã®è¯ãåžæ°ãšããŠãç§ãã¡ã¯åžžã«dispose()
ã§ãµãã¹ã¯ãªãã·ã§ã³ããªãªãŒã¹ããŸãã
ãŠã£ãžã§ããããªãŒã§ã¯ãFABãã¿ã³ïŒãããŒãã£ã³ã°ã¢ã¯ã·ã§ã³ã®ãããã¿ã³ïŒã®onPressedãã³ãã©ãŒã調æŽããã ãã§ãã
floatingActionButton: new FloatingActionButton( onPressed: MyApp.model.incrementCounter, tooltip: 'Increment', child: new Icon(Icons.add), ),
ãã®ããã«ããŠãStreamã䜿çšããŠãViewãšModelãæ確ã«åé¢ããŸããã
StreamBuilderãé©çšãã
åºæ
å¿
èŠã«å¿ããŠinitState()
ããã³setState()
ã䜿çšãã代ããã«ãFlutterã«ã¯äŸ¿å©ãªStreamBuilder
ãŠã£ãžã§ãããä»å±ããŠããŸãã ãæ³åã®ãšãããStreamé¢æ°ãšãStreamãæ°ããå€ãè¿ããã³ã«åŒã³åºãããã³ã³ã¹ãã©ã¯ã¿ãŒã¡ãœãããåããŸãã ãããŠä»ãæ瀺çãªåæåãšãªãªãŒã¹ã¯å¿
èŠãããŸããïŒ
body: new Center( child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Text( 'You have pushed the button this many times:', ), StreamBuilder<int>( initialData: 0, stream: MyApp.model.counterUpdates, builder: (context, snappShot) { String valueAsString = 'NoData'; if (snappShot != null && snappShot.hasData) { valueAsString = snappShot.data.toString(); } return Text( valueAsString, style: Theme.of(context).textTheme.display1, ); }), ], ), ),
ã»ãŒå®äºã§ããçŽæããŸãã ç¥ã£ãŠããã¹ã3ã€ã®ããšã次ã«ç€ºããŸãã
次ã®æçš¿ã§ã¯ãã¹ã¬ããå
ã®ããŒã¿ãå€æãããã®å Žã§ãããè¡ãæ¹æ³ãèŠãŠãããŸãã 蚌æ ãšéèŠãªãã£ãŒãããã¯ãèªãã§ãããScott Stollã«æè¬ããŸãã