Comments (7)
Hey there -- in this case, I think you have the right approach (setting a flag to know to navigate). However, rather than using that information to display a button, you can listen to the model yourself to perform the navigation.
Every model can be listened to using addListener
. After navigating, or when your Widget is disposed, be sure to perform a removeListener
as well.
You would need a StatefulWidget to manage this listener, setting up the addListener
call in the didChangeDependencies
method and running removeListener
in the dispose
function.
It looks like this:
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
void main() {
runApp(MyApp(
model: NavigationModel(),
));
}
class MyApp extends StatelessWidget {
final NavigationModel model;
const MyApp({Key key, @required this.model}) : super(key: key);
@override
Widget build(BuildContext context) {
return ScopedModel<NavigationModel>(
model: model,
child: MaterialApp(
title: 'Navigation Demo',
home: LoginScreen('Login'),
),
);
}
}
class NavigationModel extends Model {
bool _navigate = false;
bool get navigate => _navigate;
void onSubmit(String username, String password) {
// perform some validation, call a backend, etc.
// Then, if all that succeeds:
_navigate = true;
notifyListeners();
}
}
class LoginScreen extends StatefulWidget {
final String title;
LoginScreen(this.title);
@override
LoginScreenState createState() {
return new LoginScreenState();
}
}
class LoginScreenState extends State<LoginScreen> {
final emailController = TextEditingController();
final passwordController = TextEditingController();
// You cannot access the scoped model in the `initState` function because the
// `context` variable has not been established. Therefore, you need to access
// it in the `didChangeDependencies` method.
//
// Note: This function can be called several times, but adding the exact same
// listener (the _navigationListener method) to the model will not result
// in the function being called multiple times when the data changes.
@override
void didChangeDependencies() {
ScopedModel.of<NavigationModel>(context).addListener(_navigationListener);
super.didChangeDependencies();
}
@override
void dispose() {
// Make sure to clean up after ourselves by removing the listener!
ScopedModel.of<NavigationModel>(context)
.removeListener(_navigationListener);
// Also dispose of the controllers...
emailController.dispose();
passwordController.dispose();
super.dispose();
}
// This function will be run every time the model changes! We will use it to
// check the navigate boolean. If it's set to true, we'll push a new screen!
//
// If not, we won't do anything.
void _navigationListener() {
if (ScopedModel.of<NavigationModel>(context).navigate) {
// In this case, since it's a login Screen and we don't want the user to
// go "Back" to it, we push a replacement
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => SecondScreen()));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(
children: <Widget>[
TextField(
controller: emailController,
decoration: InputDecoration(hintText: 'Email'),
),
TextField(
controller: passwordController,
decoration: InputDecoration(hintText: 'Password'),
),
RaisedButton(
child: Text('Login'),
onPressed: () => ScopedModel.of<NavigationModel>(context)
.onSubmit(emailController.text, passwordController.text),
)
],
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Screen'),
),
body: Center(
child: Text('Logged in!'),
),
);
}
}
from scoped_model.
In my case the line in dispose method is causing an exception to be thrown, the application keeps running though.
Looking up a deactivated widget's ancestor is unsafe. At this point the state of the widget's element tree is no longer stable. To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling inheritFromWidgetOfExactType() in the widget's didChangeDependencies() method.
It's gone when I comment it out.
The only difference I see that I'm doing is in _navigationListener I use
Navigator.pushReplacementNamed(context, '/home');
Instead of MaterialPage. Any way to fix that?
from scoped_model.
My solution is instead of use Navigator.pushReplacement
I use Navigator.push().then((value) => Navigator.pop())
. I think this is not a right approach.
from scoped_model.
Thank you for the detailed answer.
It is working beautifully...
from scoped_model.
Or a really dirty solution use a navigatorKey
Create a static key
import 'package:flutter/widgets.dart';
class SfcKeys {
static final navKey = new GlobalKey<NavigatorState>();
}
in your main.dart set the navigationKey
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SFC',
navigatorKey: SfcKeys.navKey,
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.brown,
fontFamily: 'OpenSans',
),
home: SplashScreen(),
localizationsDelegates: [
_newLocaleDelegate,
const AppTranslationsDelegate(),
//provides localised strings
GlobalMaterialLocalizations.delegate,
//provides RTL support
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: application.supportedLocales(),
routes: routes,
);
}
and then in your model
final navigatorKey = SfcKeys.navKey;
navigatorKey.currentState
..push(MaterialPageRoute(
builder: (context) => AlertWidget(
title: "Error",
message: error.message,
ok: "OK",
)));
from scoped_model.
sorry @xalikoutis but what is the idea exactly u still passed context in MaterialPageRoute where did u get that from in your model
from scoped_model.
You dont pass it. It is just the context from currentState
from scoped_model.
Related Issues (20)
- Some widget don't refresh after calling notifyListener in flutter 1.22.1
- bloc model value fetch in init function not working
- can't run
- can't run
- Error: Could not find the correct ScopedModel.
- Testing when using scopedModelDescendant HOT 2
- 单独抽离一个方法 如何修改值?
- 不继承 ScopedModelDescendant() 如何修改值?
- void initState() 方法里如何修改值?
- Not Working error
- Target of URI doesn't exist: 'package:scoped_model/scoped_model.dart'.
- Publish null safe stable version
- Error: Could not find the correct ScopedModel. To fix, please: * Provide types to ScopedModel<MyModel> * Provide types to ScopedModelDescendant<MyModel> * Provide types to ScopedModel.of<MyModel>() * Always use package imports. Ex: `import 'package:my_app/my_model.dart'; If none of these solutions work, please file a bug at:
- Error: Could not find the correct ScopedModel. To fix, please: * Provide types to ScopedModel<MyModel> * Provide types to ScopedModelDescendant<MyModel> * Provide types to ScopedModel.of<MyModel>() * Always use package imports. Ex: `import 'package:my_app/my_model.dart'; If none of these solutions work, please file a bug at:
- Exception has occurred. ScopedModelError (Error: Could not find the correct ScopedModel.
- scoped_model issues HOT 6
- Scoped Model - not working after go back to previous page
- Model notifyListeners closes EndDrawer
- ScopedModel
- scoped_model.of() issue HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from scoped_model.