google / flutter_flux Goto Github PK
View Code? Open in Web Editor NEWImplementation of the Flux framework for Flutter
Home Page: https://flutter.io
License: Apache License 2.0
Implementation of the Flux framework for Flutter
Home Page: https://flutter.io
License: Apache License 2.0
There are some tab pages like fragment on android, I use constructor arguments to conotrol their stores. Like this:
List<GankPage> pages = [
TabPage('aaa'),
TabPage('bbb'),
]
class TabPage extends StoreWatcher {
String type;
StoreToken pageStoreToken;
TabPage({Key k, this.type}) : super(key: k);
@override
void initStores(ListenToStore listenToStore) {
pageStoreToken = StoreToken(PageStore(this.type));
listenToStore(pageStoreToken);
pageAction.call();
}
}
If I write like this, when I switch tab the old actions will be called.
I saw the note is that stores should not depend on any constructor parameters.
Any suggetions?
Could you upgrade the instructions as i want to play around with this example...
env:
x-MacBook-Pro:chat_app apple$ flutter doctor
[✓] Flutter (on Mac OS, channel master)
• Flutter at /usr/local/flutter/flutter
• Framework revision 16ce090fde (5 hours ago), 2016-11-01 20:34:36
• Engine revision 63e71803de
• Tools Dart version 1.21.0-dev.2.0
[✓] Android toolchain - develop for Android devices (Android SDK 24.0.3)
• Android SDK at /Users/apple/Library/Android/sdk
• Platform android-24, build-tools 24.0.3
• ANDROID_HOME = /Users/apple/Library/Android/sdk
• Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
[✓] iOS toolchain - develop for iOS devices (Xcode 8.1)
• XCode at /Applications/Xcode.app/Contents/Developer
• Xcode 8.1, Build version 8B62
[x] Flutter IDE Support (No supported IDEs installed)
• IntelliJ - https://www.jetbrains.com/idea/
[✓] Connected devices
• None
x-MacBook-Pro:chat_app apple$
error:
x-MacBook-Pro:chat_app apple$ pwd
/Users/apple/workspace/go/src/github.com/flutter/flutter_flux/example/chat_app
x-MacBook-Pro:chat_app apple$ pub get
Could not find a file named "pubspec.yaml" in "/Users/apple/workspace/go/src/github.com/flutter/flutter_flux/example/chat_app".
x-MacBook-Pro:chat_app apple$
removed unused dart:async as Future and Streams are already implemented in dart:core as per Dart 2.1
Which means moving to new Gradle build as well as some changes in the Flutter API itself (ListTile
instead of ListItem
, ListView
instead of Block
, etc.).
I've already done so locally and got the app running with today's Flutter version. I can also submit a pull request, but should I put the updated example in a new folder or just overwrite example/chap_app
?
Hey all, trying out flutter_flux in a project, but can't seem to get the correct flutter_flux source pulled down. I have defined flutter_flux: 4.0.1
in my pubspec.yaml, but when I look at the Dart Packages in Android Studio the code is not correct when compared to the GitHub repo for flutter_flux 4.0.1. For example, here is a the StoreWatcherMixin
signature from my local machine: abstract class StoreWatcherMixin implements State<dynamic>
and here is the same on GitHub: abstract class StoreWatcherMixin<T extends StatefulWidget> implements State<T>
. I have tried re-installing everything, clearing the cache, cleaning the project... I am out of idea. Any thoughts?
Flutter stateless widgets have build method. That's where you build your widget. Stateful widgets on other hand have createState method, and are delegating build to State class.
What's confusing to me that StoreWatcher is a StatefulWidget, but it has both build and createState methods. As far as I understood it, you can use build when you don't need extra state, so you don't create extra class. But if you need it, you can override createState class and have StoreWatcherState.
So I debugged it, and when you override createState on StoreWatcher, the build method in StoreWatcher is ignored, and State class will build a widget. Which is OK, but now you cannot remove the StoreWatcher build method because it needs concrete implementation? Am I doing something wrong?
IDE: VSCode
Doesn't seem to preclude builds and debugging, however is triggering a heap of 'errors' in analyzer.
Thoughts?
`[✓] Flutter (Channel dev, v0.10.1, on Mac OS X 10.13.6 17G65, locale en-NZ)
• Flutter version 0.10.1 at /Users/greg/Library/Developer/flutter
• Framework revision 6a3ff018b1 (13 days ago), 2018-10-18 18:38:26 -0400
• Engine revision 3860a43379
• Dart version 2.1.0-dev.7.1.flutter-b99bcfd309
[✓] Android toolchain - develop for Android devices (Android SDK 28.0.3)
• Android SDK at /Users/greg/Library/Android/sdk
• Android NDK at /Users/greg/Library/Android/sdk/ndk-bundle
• Platform android-28, build-tools 28.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)
• All Android licenses accepted.
[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 10.1, Build version 10B61
• ios-deploy 1.9.2
• CocoaPods version 1.5.3
[✓] Android Studio (version 3.2)
• Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin version 29.1.1
• Dart plugin version 181.5656
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)
[✓] VS Code (version 1.28.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 2.19.0
[!] Connected device
! No devices available! Doctor found issues in 1 category.greg@iMac:~/Projects/Tierra/logmate_flutter$`
I am referring to the example provided in this repo.
https://github.com/google/flutter_flux/blob/master/example/lib/main.dart#L62
The handleChatMessageStoreChanged
function is called with the Store parameter and from the example it looks like, the downcasted store is assigned to a local scoped store and not the widget's store directly.
Can that function be written as
class ChatScreenState extends State<ChatScreen>
with StoreWatcherMixin<ChatScreen> {
// Never write to these stores directly. Use Actions.
ChatMessageStore messageStore;
// ...
void handleChatMessageStoreChanged(Store store) {
// ChatMessageStore messageStore = store; // instead of this local scoped store ...
messageStore = store; // ... assign to widget's store
if (messageStore.currentMessage.isEmpty) {
msgController.clear();
}
setState(() {});
}
// ...
}
If this is not okay, I would like to know why.
We should either bring it up to date (reported by @harveynick), or remove it from the Flutter organization.
I'm getting the following error:
Because cronicalia_flutter depends on flutter_flux >=4.0.1 which requires SDK version >=1.19.0 <2.0.0, version solving failed.
Could you update the pubspec.yaml?
Instead of
environment:
sdk: ">=1.24.0 <2.0.0"
use
environment:
sdk: ">=1.24.0 <3.0.0"
The title of this issue could be a little misleading but I was not sure how else to describe my thought process, so please stay with me and read along.
I am writing a Flutter application that uses flutter_flux. I have a few stores and a few views (widgets) so far. Right now I am in a dilemma on how to do the network API calls. My widget loads but does not have any data to display yet, which is fine, but now it needs to call my network API service that responds with data. Here is what I am thinking design-wise. Please share your opinions on it.
In this design, the widget kicks off an action something like fetchMessages
and the store listening to this action MessageStore
receives a call to this action. In the action callback, this store kicks the network call that returns Future
. In the then()
callback of that Future
, this store mutates it's own data and calls trigger()
so that the original view that started this now receives a callback. Similarly, also in catchError
of the same Future
, this store calls trigger()
with some other mutation that maintains error states.
In this design, I am not exactly sure where do I call action from the widget? In build
or in initState
?
My thinking is that in initState
the widget will grab data from store but it will be null
or empty initially, and build
will render empty view but at the same time, kickstarts the cycle described above, which calls back to the widget later and the build
function now has data to render, re-grabbed from store.
Do you think it is a good pattern? It still abides to Flux's unidirectional data flow and does not let store data to be manipulated in any way other than an action callback.
Hi,
I've been wrestling with this for a while now and can't see what is going wrong, but my StoreWatcherMixin widget does not get build() called after setting state in the flux store.
Main.dart:
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
State createState() => new AppState();
}
class AppState extends State<MyApp>
with StoreWatcherMixin<MyApp> {
var appStore;
@override
void initState() {
super.initState();
appStore = listenToStore(_appStoreToken);
}
@override
Widget build(BuildContext context) {
...
return new SecondPage(_appStoreToken);
}
The store:
final Action<List<Foo>> setFoos = new Action<List<Foo>>();
final AppStore _store = new AppStore();
final StoreToken _appStoreToken = new StoreToken(_store);
class AppStore extends Store {
List<Foo> _allFoos = new List<Foo>();
List<ArkhamDBCardPack> get allFoos => _allFoos;
AppStore() {
triggerOnAction(setFoos, (value) => _allFoos = value);
}
}
Second page:
class SecondPage extends StatefulWidget {
final StoreToken _storeToken;
SecondPage(this._storeToken);
@override
State createState() => new SecondPageState(_storeToken);
}
class SecondPageState extends State<SecondPage>
with StoreWatcherMixin<SecondPage> {
var appStore;
final StoreToken _storeToken;
List<Foo> foos;
SecondPageState(this._storeToken);
@override
void initState() {
super.initState();
debugPrint('x');
appStore = listenToStore(_storeToken);
foos = appStore.allFoos;
}
@override
Widget build(BuildContext context) {
debugPrint('rebuilding');
return new IconButton(
icon: new Icon(Icons.refresh),
onPressed: () async {
var data = await fetchFoos();
setFoos.call(data);
},
)
}
}
This isn't the exact code, but its close enough. The first time it runs, I press the button on the second page to fetch the data and call setFoos. debugPrints show that it has set the value correctly into the store, but the build() and debugPrint('rebuilding') are never called a second time.
What am I doing wrong? I really want to get this working as flutter and flux seem like a great tech. Thanks in advance!
in store.dart
,
class Store {
// ...
void triggerOnConditionalAction<T>(Action<T> action, bool onAction(T payload)) {
assert(action != null);
action.listen((dynamic payload) async {
// Action functions must return bool, or a Future<bool>.
dynamic result = onAction(payload);
bool wasChanged;
if (result is Future) {
wasChanged = await result;
} else {
wasChanged = result;
}
if (wasChanged) {
trigger();
}
});
}
// ...
}
the 2nd param onAction
defined bool
return type. it should be dynamic
.
If a method is listening to an action then for first time it gets hit once, then for next time if user gets back to the same page then the method gets hit twice and on third time its 3 times and increases every time.
Below is a code to simulate the same on click of Next a action is called and on action change the user is taken to second page, but on second time the action listening method gets hit twice.
import 'package:flutter/material.dart';
import 'package:flutter_flux/flutter_flux.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHome(),
);
}
}
//========
class MyHome extends StatefulWidget {
@override
_MyHomeState createState() => _MyHomeState();
}
class _MyHomeState extends State<MyHome> with StoreWatcherMixin<MyHome> {
AppStore store;
@override
void initState() {
store = listenToStore(appStoreToken);
changeStatus.listen(_openSetupDialogue);
super.initState();
}
void _openSetupDialogue(dynamic payload){
if(payload == true) {
print("method got hit");
Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()));
}
}
@override
Widget build(BuildContext context) {
return RaisedButton(
child: Text("Next"),
onPressed: (){
changeStatus(true);
},
);
}
}
//===========
class SecondPage extends StatefulWidget {
@override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
@override
Widget build(BuildContext context) {
return RaisedButton(
child: Text("back"),
onPressed: (){Navigator.push(context, MaterialPageRoute(builder: (context) =>MyHome()),
);
},
);
}
}
//===========
class AppStore extends Store {
bool state = true;
AppStore(){
triggerOnAction(changeStatus, (status){
state = status;
});
}
bool get getAppStore => state;
}
final Action changeStatus = Action<bool>();
final appStoreToken = StoreToken(AppStore());
Using StoreWatcher, how can I call setState() inside my custom handler?
class MyWidget extends StoreWatcher {
@override
void initStores(ListenToStore listenToStore) {
listenToStore(storeToken, customHandleStoreChanged);
}
void customHandleStoreChanged(Store store) {
// ...
// setState(() {});
}
}
Someone plan to bring compatibility to flutter web ? or who know what i need change to achieve it runing on web ?
I have several triggerOnAction definitions in my store, and when I used async
functions the store is never triggered.
Is this a working as designed or a bug?
If it is a bug I can setup a sample to demonstrate
This is an experimental package and does not have official support from the Flutter team. However, feedback is most welcome!
Should I post my questions/feedback here, on the Flutter mailing list, SO, or somewhere else?
Hi,
I've been spiking out flutter flux and could use some guidance. I have a repo here. Note that my dependency on flutter_flux is a source dependency, due to the binaries on pub being old.
My use case is a login dialog. I already have it working in plain old flutter, but I want to separate the logic out, hence my spiking with flutter_flux. I've left a few TODO comments in the code, but in short I'm a bit stuck on how to do things The Right Way™.
And there's one debilitating bug in my code that I've not found a workaround for yet. I need to pop the modal when authentication succeeds, but I'm doing so from my build
method, which of course triggers a setState() or markNeedsBuild() called during build
assertion violation. I'm just not sure where else I could do this.
Can someone please offer some guidance?
Thanks
If i create a widget that need to cancel stream subscriptions of firebase in the dispose method how can I do it with a storewatcher?
In the example, when we commit a new message, the _currentMessage
is emptied but the TextField
does not reflect that changes.
This is the code in the store:
triggerOnAction(commitCurrentMessageAction, (ChatUser me) {
final ChatMessage message =
new ChatMessage(sender: me, text: _currentMessage);
_messages.add(message);
_currentMessage = '';
});
The view uses a TextEditingController
as a controller for the TextField
Widget so I understand why it is not updated.
How can we empty the TextField
from the Store with flutter_flux?
I'd really like to use this library for flutter. Will it be maintained over time or is it just experimental?
Thanks for your hard work.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.