flutterando / modular Goto Github PK
View Code? Open in Web Editor NEWA smart project structure
Home Page: https://pub.dev/packages/flutter_modular
License: Other
A smart project structure
Home Page: https://pub.dev/packages/flutter_modular
License: Other
Seria interessante a possibilidade de criar rotas que direcionam para dialogs, especialmente os do tipo fullscreen de acordo com a especificação do Material Design, possibilitando a criação de um módulo com ciclo de vida limitado à vida do mesmo, o que seria bem útil em casos como telas de detalhes de produto, por exemplo, entre outros.
Permitir ao usuário escolher entre rotas nomeadas ou não na hora do slidy start
Adicionar padrão Pedantic nos códigos gerados
Ao gerar uma page colocar o construtor antes de todas as declarações. e colocar Aspas Simples no this.title da page gerada.
final String title;
const HomePage({Key key, this.title = "Home"}) : super(key: key);
to
const HomePage({Key key, this.title = 'Home'}) : super(key: key);
final String title;
Mudar para Aspas Simples nos Testes gerados:
test("First Test") to test('First Test')
Colocar Return type no main dos testes
main() to void main()
We have a small issue in the ModularApp
widget as we are calling the function that dispose the injected object after the super.dispose()
function.
@override
void dispose() {
super.dispose();
widget.module.cleanInjects();
print("-- ${widget.module.runtimeType.toString()} DISPOSED");
}
We also have the same issue in the consumer_widget
class:
@override
void initState() {
_inject = widget.inject ?? Inject();
value = _inject.get<T>();
value.addListener(listener);
super.initState();
}
how to pass arguments to a change notifier class ?
Exibir erro corretamente quando nenhuma rota for passada para um modulo.
Para reproduzir o erro basta deixar routers vazio;
AppModule:
@override
List<Router> get routers => [];
A validação de recursividade nos Binds está sendo disparada em um caso onde não deveria. Segue um exemplo:
List get binds => [
Bind((i) => Dependence01()),
Bind((i) => Dependence02(i.get<Dependence01>())),
Bind((i) => Dependence03(i.get<Dependence01>(), i.get<Dependence02>())),
Bind((i) => HomeController(i.get<Dependence03>())),
];
Se eu não estiver errado, o problema ocorre pois a validação se baseia em uma lista simples de "Types", onde não se pode repetir o "Type". No exemplo acima, o type "Dependence01" está sendo adicionado duas vezes nesta lista de controle. Para que não ocorra o erro, talvez, a validação deva ser feita para cada linha da árvore de dependências, individualmente.
HomeController > Dependence03 > Dependence01
HomeController > Dependence03 > Dependence02 > Dependence01
Is it possible to be have nested routes while preserving the state of Navigators?
Hi, thank you for this package!
Is possible implement nested route using modular?
I need of tab bar and every widget must have our routes
I want try new different approach using Modular instead classic method using navigator inside the widget screen.
Thanks
Error when calling the route using Modular.to.pushNamed
My code
Works well
Navigator.pushNamed(context, '/datail/${homeController.text}');
Does not work
Modular.to.pushNamed('/datail/${homeController.text}');
App Module
@override List<Router> get routers => [ Router('/', child: (_, args) => HomePage()), Router('/datail/:text', child: (_, args) => DatailPage( text: args.params['text'], )), ];
Error
Add Modular.navigatorKey in your MaterialApp;
return MaterialApp(
navigatorKey: Modular.navigatorKey,
...
.
'package:flutter_modular/src/modular_base.dart':
Failed assertion: line 94 pos 9: '_navigatorKey != null'
I have a suggestion, even if it comes from me it doesn't mean it's good...
I would like to use a global flag in any module. This would make Bind global and work even if the Module had not been called. Roughly speaking, it would be as if it were in the AppModule even though it is in a child Module, being accessible to any other module.
class LoginModule extends ChildModule {
@override
List<Bind> get binds => [
Bind((i) => AuthStore(), global: true),
]
....
}
In this example, AuthStore would be visible to the entire application even if LoginModule is not instantiated.
Ai would not need to put the AuthStore in the Bind of the AppModule, as it would already be global. In practice it would work as if it were in the AppModule.
Is that a good idea?
Like I talked to @jacobaraujo7 ,
The scenario is like this:
When executing step 4, it should dispose NewModule, but it never happens. That can cause issues when navigating back to NewModule.
It only disposes correctly if I navigate to "/" inside the "/new" route (first route inside NewModule), if I try to navigate from 2+ page in stack, it doesn't dispose. You can test this scenario uncometing the line 24 inside new_page.dart
Minimal reproducible project:
https://github.com/Gustav0ar/modular_route_bug
Olá,
Estou tentando passar um argumento no Router para um Module, não para um Widget simples, porém não existe essa opção (ou não encontrei).
Existe essa possibilidade?
I'm getting the following error when trying to navigate to routes declared outside AppModule:
Could not find a generator for route RouteSettings("/product/1/select-cut-type", null) in the _WidgetsAppState.
app_module.dart
@override
List<Router> get routers => [
Router('/', module: HomeModule()),
Router('/product', module: ProductModule()),
];
product_module.dart
@override
List<Router> get routers => [
Router('/:id', child: (_, args) => ProductPage(id: args.params['id'])),
Router('/:id/select-cut-type ', child: (_, args) => SelectCutTypePage(id: args.params['id'])),
];
Inside ProductPage, I try to navigate to SelectCutTypePage using the following command:
Modular.to.pushNamed('/product/$id/select-cut-type');
It works fine if I declare the route inside AppModule like this:
@override
List<Router> get routers => [
Router('/', module: HomeModule()),
Router('/product', module: ProductModule()),
Router('/product/:id/select-cut-type', child: (_, args) => SelectCutTypePage(id: args.params['id']))),
];
EDIT 1:
Forgot to add ProductPage content:
import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:pedras_mobile/app/modules/product/select_cut_type/select_cut_type_controller.dart';
class SelectCutTypePage extends StatefulWidget {
final String title;
final String id;
const SelectCutTypePage({Key key, this.title = "SelectCutType", this.id}) : super(key: key);
@override
_SelectCutTypePageState createState() => _SelectCutTypePageState();
}
class _SelectCutTypePageState extends ModularState<SelectCutTypePage, SelectCutTypeController> {
//use 'controller' variable to access controller
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(
children: <Widget>[],
),
);
}
}
Ajust needed on home_modular.dart, line 23 at example/lib/app/modules/home
from:
param: args.params['id'],
to:
param: int.parse(args.params['id']),
Hi, when I used to create some InheritedWidgets and place them between the GenerateRoute method and the route resolve so I could create my own default implementation of something that depends on a context (default widget that a Flushbar shows, for example).
static dynamic pageBuilder(Widget widget) =>
MaterialPageRoute(builder: () => ExampleInheritedWidget(child: widget));
I know that if I do something like this with the mondule concept is probably going to be wrong, because of adding a dependency for any child that uses it, can't we create a method for the child module so we can "setup" the route after it change?
@override
List<Router> get routers => [
Router('/', child: (_, args) => HomePage()),
];
then
@override
thatMethod(routeToRender) => ExampleInheritedWidget(child: routeToRender);
This is just easier way of doing that, I think that placing the ExampleInheritedWidget as a parent of all the routes manually is too much.
Thanks!
Queria saber o que vocês acham disso.
Seria interessante criar um NavigatorService em que possamos injetar e pegar em qualquer parte do aplicativo sem a necessidade do context.
Gostaria de saber se isso traria alguma implicação, principalmente na abertura de dialogs e Snackbar de cada página.
A ideia é fugir da arvore de elementos mais uma vez para possibilitar o uso dos metodos de navegação em uma classe controller.
Podemos chegar a isso trabalhando com uma Globalkey no MaterialApp, nos fornecendo tudo oq precisamos.
O que acham disso?
Hoje precisei implantar uma classe que nao podia ser singleton, e quando fui procurar no Bind ele nao me da essa opção de escolha assim como BlocPattern fornecia.
Como faz agora? Ou ainda não foi implementado?
Adaptei ao projeto do jacob de login e dá o seguinte erro:
Failed assertion: line 2335 pos 12: '!_debugLocked': is not true.
disposer = autorun((_) {
final auth = Modular.get<AuthController>();
if (auth.status == AuthStatus.Authenticated) {
Modular.to.pushReplacementNamed('/home');
} else if (auth.status == AuthStatus.NotAuthenticated) {
print('eveio');
Modular.to.pushReplacementNamed('/login');
}
});
só consegui rodar utilizando
Timer.run(() {
Modular.to.pushReplacementNamed('/home');
});
I'm getting some errors when I run an entire test file using "flutter test", but each test passes if tested individually.
So, I realized that it happens because my controller (a Mobx Store generated with Slidy) is not being recreated each time I call InitModules() inside setUp() function. The controller seems to be a singleton that is retrieved each time I call Modular.get() and even a call to initModules() can't recreate the controller.
By not being recreated after each test, the controller keeps dirty data from the previous test when starting a new test, leading to undesirable behavior.
Let me share some code to clarify what I'm trying to achieve.
The tests file:
main() {
setUp((){
// does not reload the entire module, the controller keeps its state after each test
initModule(AuthModule());
});
testWidgets('test 1') ...
testWidgets('test 2') ...
testWidgets('test 3') ...
group('group 1', () {
testWidgets('test 4') ...
testWidgets('test 5') ...
});
testWidgets('test 6') ...
The Module:
class AuthModule extends ChildModule {
@override
List<Bind> get binds => [
Bind((i) => LoginErrorStateController()),
Bind((i) => LoginController()),
];
@override
List<Router> get routers => [
Router('/', child: (_, args) => LoginPage()),
];
static Inject get to => Inject<AuthModule>.of();
}
Inside the page, where the controller is retrieved using Modular:
class LoginPage extends StatefulWidget {
final String title;
const LoginPage({Key key, this.title = "Login"}) : super(key: key);
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
LoginController controller = Modular.get<LoginController>();
...
Should initModule(AuthModule()) restart the entire module, including its binds, or this is out of the scope of this function?
What's the best practice to reset the whole module (including its bindings) before starting a new widget test? To achieve this behavior, I'm currently using this code, but I'm not sure this is the more efficient way to do this.
setUp((){
// Removes the entire module
Modular.removeModule(AuthModule());
// Restart the module
initModule(AuthModule());
});
Thanks in advance.
I have the following test case that opens and closes an AlertDialog.
testWidgets('Status should back to IDLE when INVALID dialog is closed.', (WidgetTester tester) async {
LoginController loginController = Modular.get();
AlertDialog dialog = await showInvalidDialog(tester, loginController);
// Closes the dialog
Finder dialogCloseButton = find.descendant(of: find.byType(AlertDialog), matching: find.byType(FlatButton));
await tester.tap(dialogCloseButton);
await tester.pump();
expect(find.byType(AlertDialog), findsNothing);
expect(loginController.loginState, equals(LoginState.IDLE));
});
The Dialog:
class _LoginPageState extends State<LoginPage> {
LoginController controller = Modular.get<LoginController>();
ReactionDisposer disposer;
@override
void initState() {
super.initState();
disposer = autorun((_) {
if(controller.loginState == LoginState.INVALID) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(controller.error.formErrorMessage.invalidTitle),
content: Text(controller.error.formErrorMessage.invalidContent),
actions: <Widget>[
FlatButton(
child: Text("OK"),
onPressed: () {
controller.setLoginState(LoginState.IDLE);
Navigator.pop(context);
},
)
],
),
);
}
});
}
When the AlertDialog is open, if I try to close it using Modular.to.pop() method, I get this exception during the test execution:
══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
The following assertion was thrown while handling a gesture:
Add Modular.navigatorKey in your MaterialApp;
return MaterialApp(
navigatorKey: Modular.navigatorKey,
...
.
'package:flutter_modular/src/modular_base.dart':
Failed assertion: line 39 pos 9: '_navigatorKey != null'
When the exception was thrown, this was the stack:
#2 Modular.to (package:flutter_modular/src/modular_base.dart:39:9)
Although the exception's error message is very helpful, I already have "navigatorKey: Modular.navigatorKey" set inside MaterialApp().
The only way to get this code working is to make a replacement of Modular.to.get() by Navigator.pop(context).
Using Navigator.pop(context), the test passes Ok.
In debug mode, Modular.to.get() and Navigator.pop() have the same behaviour, with no exceptions. The error only occurs inside test cases.
Am I missing some point with Modular.to.get() usage or there's some kind of bug related to this method when used inside test cases or, particularly, inside Dialog widgets?
Thanks in advance.
Hi, thanks for amazing lib!
I'm trying to find a way to test a separate widget which use "store". Is there a way to wrap separate widget to mocked "store"
For example, i have AuthModule
class AuthModule extends MainModule {
@override
List<Bind> get binds => [
Bind((i) => AuthStore())
];
....
@override
Widget get bootstrap => AppWidget();
}
And i have widget witch use AuthStore
class LoginForm extends StatelessWidget {
@override
Widget build(BuildContext context) {
final store = Modular.get<AuthStore>();
//...
}
}
How to mock AuthStore if i want to test only LoginForm widget? I did find this point in documentation.
Ontem a partir do vídeo do Darlan no canal, gostei muito do Get e decidi usar o modal dele, achei simples e muito legal, já que as rotas estou utilizando as do próprio Modular e funcionam perfeitamente. Mas percebi que se eu usar um componente do mesmo tipo, Modular ou Get ou outro afim que eu tenha que setar a propriedade navigatorKey do MaterialApp, em ambos, tanto o Get quanto o Modular temos que passar o navigatorKey gerado pelo componente. Caso eu escolha um deles, o outro para de funcionar pq desconhecerá a key gerada pelo outro componente.
Eu não observei nenhuma propriedade ou método no Modular para que eu possa passar pra ele o key que deve usar.
Coçou a mão da POG para fazer funcionar os 2 juntos.
Não sei se terá implicações em outras partes do Modular, mas no pouco que testei o meu app funcionou com os 2 juntos e certinho minhas rotas voltaram a funcionar.
O que eu fiz:
No modular_base.dart acrescentei:
static set navigatorKey(GlobalKey<NavigatorState> key) => _navigatorKey = key;
A qual eu pego da key que o Get gera e no MaterialApp eu passo:
GlobalKey<NavigatorState> keyget = Get.key;
Modular.navigatorKey = keyget;
navigatorKey: keyget,
Bom, estou passando aqui e não no Get pela facilidade de relato em português, só isso. rs. Conheço inglês mas relatar tudo ia ser bem difícil.
Há alguma forma de evitar o dispose do Controller de um ModuleWidget?
Tenho uma ModuleWidget que uso dentro de um BottomNav,
Mesmo usando varias formas e manter a instancia, o Controller sempre é recriado
e as requisições lá são refeitas quando troco de um ModuleWidget para outro.
`class ServicesModule extends ModuleWidget {
@OverRide
List get binds => [
Bind((i) => ServicesController(i.get())),
Bind((i) => ServicesRepository()),
];static Inject get to => Inject.of();
@OverRide
Widget get view => ServicesPage(key: PageStorageKey('service'));}`
Sei que posso "bindar" no pai, mas achei legal dentro do ModuleWidget
Desde já obrigado!
Na ultima atualização foi esquecido de colocar esse print do ModularApp em modo debug
modular/lib/src/widgets/modular_app.dart
Line 27 in 40abf91
Just this simple question: how to use hero transitions with modular router?
Olá, boa tarde!
Estou com um problema de roteamento nomeado. Quando navego do HomeModule para o RouteOneModule (home/route-one) não tenho problemas, porém o problema está na navegação do RouteOneModule para o RouteTwoModule (home/route-one/route-two), onde recebo um erro de Stack Overflow
I/flutter (22815): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
I/flutter (22815): The following StackOverflowError was thrown while handling a gesture:
I/flutter (22815): Stack Overflow
I/flutter (22815):
I/flutter (22815): When the exception was thrown, this was the stack:
I/flutter (22815): #1 String._setRange (dart:core-patch/string_patch.dart)
I/flutter (22815): #2 _StringBase.replaceRange (dart:core-patch/string_patch.dart:606:22)
I/flutter (22815): #3 _StringBase.replaceFirst (dart:core-patch/string_patch.dart:593:12)
I/flutter (22815): #4 Modular._searchInModule (package:flutter_modular/src/modular_base.dart:170:43)
I/flutter (22815): #5 Modular._searchInModule (package:flutter_modular/src/modular_base.dart:184:20)
I/flutter (22815): #6 Modular._searchInModule (package:flutter_modular/src/modular_base.dart:184:20)
I/flutter (22815): #7 Modular._searchInModule (package:flutter_modular/src/modular_base.dart:184:20)
I/flutter (22815): #8 Modular._searchInModule (package:flutter_modular/src/modular_base.dart:184:20)
I/flutter (22815): #9 Modular._searchInModule (package:flutter_modular/src/modular_base.dart:184:20)
I/flutter (22815): #10 Modular._searchInModule (package:flutter_modular/src/modular_base.dart:184:20)
I/flutter (22815): #11 Modular._searchInModule (package:flutter_modular/src/modular_base.dart:184:20)
I/flutter (22815): #12 Modular._searchInModule (package:flutter_modular/src/modular_base.dart:184:20)
...
O que estou tentando é concatenar as rotas home/route-one/route-two
A navegação é feita por RaisedButton, tanto na HomePage quanto na RouteOnePage
RaisedButton(
child: Text('Route One -->'),
onPressed: (){
Navigator.pushNamed(context, '/route-one');
},
),
O projeto que fiz é simples, que fiz somente para testar a navegação por rotas nomeadas. Este é o link do projeto no GitHub
Seria interessante no modular o lazy loading ser opcional, fazendo a classe ser instanciada assim que módulo é iniciado, resolvendo problemas como quando é preciso que uma classe seja instanciada assim que o módulo inicia, sem precisar instância lo na view.
Poderia ser algo como:
Bind((i) => AppController, lazy: false)
I understand that the ModularState was designed to work only with the view, and dispose with it. And I don't want to change that. But let's see an example:
Imagine a Login View. With a bar with "login credentials" or the option to fill email+password. Then I detach that "credentials bar" and create a new widget for it.
Or I should make micro controllers for each widget like that. Or I should put that controller on Bind. But I just want that any ModularState child have access to it's father controllers.
Makes sense?
@jacobaraujo7 , Não sei se tem relação com esse mesmo problema de navegação que discutimos nessa issue: #11, mas com certeza tem a ver com questões de navegação.
Veja esses 2 videos:
https://drive.google.com/file/d/15ChEryT-w_2GbQL1d29efEao5z_Y_5Q0/view?usp=sharing
https://drive.google.com/file/d/1E-rEo4kIlk1vz71zX8WGDnXS_2R1N97C/view?usp=sharing
Quando navego pra outra tela com pushNamed
, e depois retorno, o build dos widgets é executado em duplicidade, e a cada vez que navega e volta aumenta mais um execução do build. Minha tela ai no video tá com 7 widgets do mesmo, e após 10 vezes que navegou pra outra tela e voltou, tem 70 builds executados (10 pra cada um dos widgets) sendo que era pra ser só 1... isso com o tempo vai pesar pra caramba na performance pois basicamente todos os widgets da tela estão rodando o build mais vezes conforme vai navegando... correto ?
No primeiro video,naveguei pra outra tela usando pushNamed
e retornei usando popAndPushNamed
. No caso eu mudei pra pop
e parou de aumentar os renders... Isso que eu não entendi, se a tela já tá no histórico de navegação e se eu navego pra ela de novo não teria que remover a parte antiga do histórico ?
No segundo video mesma coisa, estava navegando pushNamed
, e nesse caso eu realmente quero manter o histórico pra retornar, não quero usar replacement, nem apagar o histórico da navegação. Mas aí começa a novela da repetição do build... Eu quero manter o a página Home carregada pois ela é o carro chefe do app e e tem muita coisa acontecendo nela pra ficar sendo recriada do zero. E só parou de incrementar as vezes que o build dela e dos widgets que tão nela quando usei Navigator.pushNamedAndRemoveUntil(context, '/outratela', ModalRoute.withName('/outratela'));
na navegação...
Quais as ações possíveis pra melhorar essa questão de navegação e evitar esse processamento excessivo?
class AppModule extends MainModule {
@override
List<Bind> get binds => [
Bind((i) => AppController()),
];
@override
List<Router> get routers => [
Router('/', module: LoginModule()),
Router('/home', module: HomeModule(), guards: [AppGuard()]),
];
@override
Widget get bootstrap => AppWidget();
static Inject get to => Inject<AppModule>.of();
}
class AppGuard implements RouteGuard {
@override
bool canActivate(String url) {
return false;
}
}
Fala pessoal, mesmo forçando retorno para false e debugando, o canActivate não esta sendo acionado, a implementação do RouteGuard está correta?
Teria algum outro material/documentação para olhar sobre segurança de rotas?
Abraço!
Não é possível iniciar um módulo criado com --noroute
(ou seja, um ModuleWidget
) com initModule
para testes unitários porque ModuleWidget
não tem mais o mixin de ChildModule
.
Agora quando tentamos dar initModule
em um module que é ModuleWidget
:
class NotasModule extends ModuleWidget {
@override
List<Bind> get binds => [
Bind((i) => NotasController()),
];
static Inject get to => Inject<NotasModule>.of();
@override
Widget get view => NotasPage();
}
initModule(NotasModule());
Recebemos o erro:
The argument type 'NotasModule' can't be assigned to the parameter type 'ChildModule'.
Antes funcionava normalmente, mas esse commit retirou o mixin:
4a6650f#diff-9b1991b90e70f8bf922d9f6b2358e496R4
Algum motivo específico? Podemos trazer de volta ou há outro jeito de dar initModule
em um ModuleWidget
?
Estou com um problema ao acessar uma classe Bloc de outro módulo, não tenho certeza se é algum problema dos módulos ou alguma coisa que eu acabei esquecendo. Segue o fluxo abaixo:
Note que eu acesso o AppThemeBloc da mesma forma, mas quando tento acessar o CompanyBloc, ele não aceita. Apesar disso, o auto-complete preenche certinho o .to.get().
Só está funcionando instanciando o objeto da classe, conforme visto na linha 22 comentado.
Seguem demais prints:
Seria interessante adicionar a navegação nativa para CupertinoApps ou que fosse passado como parâmetro e, desta forma manter a coerência no app.
Ademais, parabéns pelo trabalho.
apos a adição do Modular.args tive um problema em algumas paginas que passavam argumentos pelo Modular.to.pushNamed("rota", arguments: Objeto). o problema acontece quando apos passar o objeto A da pagina 1 para 2 e passar outro objeto B da pagina 2 para 3 ao voltar para pagina 2 o objeto B é passado de volta para pagina 2 causando erro pois a pagina 2 esperava o objeto A não o objeto B que ela mandou para pagina 3.
Antes da atualização do Modular.args funcionava sem problema pois sempre recebia a referencia correta do objeto.
Uma sugestão para os testes dos módulos que recebem os argumentos pelo Modular.args é implementar uma função como essa no modular_base.dart para possibilitar a passagem de parâmetros ao testar as paginas ou controllers.
@visibleForTesting
static void arguments({Map<String, dynamic> params, dynamic data}) {
_args = ModularArguments(params ?? {}, data);
}
Estou iniciando um projeto com o Modular e estou com este erro. Alguém pode me ajudar ?
Tenho 2 módulos: Login e Home e uma página splash.
Meu AppModule está assim:
@override List<Router> get routers => [ Router('/', child: (_, args) => SplashPage()), Router(Routes.PAGE_HOME, module: HomeModule()), Router(Routes.PAGE_LOGIN, module: LoginModule()), ];
Compiler message:
../../../.pub-cache/hosted/pub.dartlang.org/flutter_modular-0.5.2/lib/src/modular_base.dart:372:18: Error: The getter 'isInitialRoute' isn't defined for the class 'RouteSettings'.
Does Modular provide some features to test navigation?
I'd like to test if the application properly navigates to another route when the user taps a button.
On the button pressed event, there's a command:
Modular.to.popAndPushNamed('/home');
How could I create some test-case to ensure that the button tap event navigates to another screen correctly?
Thanks in advance.
Ao realizar o pushNamedAndRemoveUntil(context, '/one/two', ModalRoute.withName('/'));
de /#/main-pass-parameter/pass-parameters/2
para /#/one/two
, a navegação acontece, porém a url não é alterada. Estou fazendo algo de errado?
Every time that I restart my app and go to the main menu ("/menu" route), the module Identify is initialized two times and one of them is disposed. I already search for what I am missing and didn't find anything. Please help me.
Restarted application in 1,806ms.
I/flutter (11409):
I/flutter (11409): *** Modular Routers ***
I/flutter (11409):
I/flutter (11409): / => SplashPage
I/flutter (11409): /menu => MenuPage
I/flutter (11409): /recipes => RecipesPage
I/flutter (11409): /register => RegisterPage
I/flutter (11409): /identify => IdentifyPage
I/flutter (11409): /identify/fill_data => FillDataPage
I/flutter (11409): /identify/driver_data => DriverDataPage
I/flutter (11409): /recipes/authorization_details => AuthorizationDetailsPage
I/flutter (11409):
I/flutter (11409): *****
I/flutter (11409):
I/flutter (11409): -- AppModule INITIALIZED
I/flutter (11409): building menu
I/flutter (11409): building menu
I/flutter (11409): -- IdentifyModule INITIALIZED
I/flutter (11409): -- IdentifyModule INITIALIZED
I/flutter (11409): -- IdentifyModule DISPOSED
My MenuPage source code:
class MenuPageState extends ModularState<MenuPage, MenuController> {
AuthController _authController = Modular.get<AuthController>();
@override
void initState() {
super.initState();
controller.selectedDrawerIndex = 0;
controller.pageController = PageController(initialPage: 0);
}
@override
void dispose() {
super.dispose();
}
List<DrawerItem> drawerItems = [
DrawerItem(
title: 'Abastecimento',
icon: Icons.directions_car,
),
DrawerItem(
title: 'Comprovantes',
icon: Icons.print,
),
DrawerItem(
title: 'Sair',
icon: Icons.input,
),
];
@override
Widget build(BuildContext context) {
print("building menu");
return Scaffold(
appBar: AppBar(
title: Text(drawerItems[controller.selectedDrawerIndex].title),
),
body: PageView(
physics: NeverScrollableScrollPhysics(),
controller: controller.pageController,
children: [
RouterOutlet(
module: IdentifyModule(),
keepAlive: false,
),
RouterOutlet(
module: RecipesModule(),
keepAlive: false,
),
]),
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(vertical: 12.0),
child: Image.asset("assets/icons/Ativo16.png")),
Container(
margin: EdgeInsets.symmetric(vertical: 12.0),
child: Column(
children: <Widget>[
Text(
"${_authController.userModel.companyName}",
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).primaryColor,
fontSize: 16,
fontWeight: FontWeight.bold),
),
Text(
"${_authController.userModel.companyId}",
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).primaryColor,
fontSize: 12,
fontWeight: FontWeight.bold),
),
],
),
),
],
),
),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: drawerItems.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: Icon(drawerItems[index].icon),
title: Text(drawerItems[index].title),
selected: index == controller.selectedDrawerIndex,
onTap: () {
controller.onSelectItem(index);
},
);
})
],
),
),
);
}
}
All code is working, but when I initialize this is happening and it bothers me
Hi,
I'm developing an app that involves chat. When the user is in chat route and clicks on notification that directs to the same chat route with a different, say, id, I need to replace existing route with a new one instead of pushing on top.
As things are currently standing, Navigator doesn't expose an API for getting the current route name.
How can I achieve this in Modular?
In addition to enum, if one one to push there custom animation, it should be easy to do?
This looks nice.
I would like to see what you think about Shaing as its so related to Routing and Security.
We have started to research dong all this here: https://github.com/getcouragenow/plugins/tree/master/links
Maybe we can collaborate on adding this to the Modular project if its wanted.
sample:
A forms have tree form. each one need a service T.
I want create a Class TFactory, which is used to switch argument to specific instance.
Then, FormModule.bind is TFactory.
is it a good way?
PS: TFactory is someone like kiwi
container.registerInstance<Character, Sith>(Sith('Anakin', 'Skywalker'), name: 'DartVader');
Hello everyone,
Thanks for your awesome package, I love it!! 🔥
I encounter a litte issue right now and I'm not sure why it's happening, could you provide any support ? 🙏
I'm trying to make my app responsive using responsive_builder and it works, but not when I just split my content in different screens.. Now when on a child route of a ChildModule I try to resize windows, first pixel changed, and modular redirect to Modular.initialRoute of this ChildModule..
Tell me what you need to investigate!!
I pushed the code in a personal repo, you can check it out here. Also app is being served here!
I guess it's because the size of window being changed, my Layout (Navbar on top and body content) is being notified so it tries to rebuild, and all my routes are under this? 🤔
This is the output:
Router = the component that manages the routes.
Route = a named path to some destination.
There is a lot of mispelled messages and concepts that would make this library weird to worldwide adoption.
Example: https://github.com/Flutterando/modular/blob/master/lib/src/inject/bind.dart:
singleton can not be false when lazy be false
Should be
singleton can not be false when lazy is false, or, better yet: 'singleton' can't be false if 'lazy' is also false
Language matters.
Hoje, domingo 16/02/2020, executando a mesma versão da sexta, me deparei com o seguinte erro:
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Stack Overflow
Esse erro aconteceu sem eu ter mexido em meu app.
Ocorre quando chamo uma rota nomeada :
Percebi que disponibilizaram nova versão este fim de semana.
Poderiam ver o que houve?
Abcs,
Luiz Leite
Launching lib\main.dart on SM J320M in debug mode...
√ Built build\app\outputs\apk\debug\app-debug.apk.
D/FlutterActivityAndFragmentDelegate(13747): Setting up FlutterEngine.
D/FlutterActivityAndFragmentDelegate(13747): No preferred FlutterEngine was provided. Creating a new FlutterEngine for this FlutterFragment.
D/FlutterActivityAndFragmentDelegate(13747): Attaching FlutterEngine to the Activity that owns this Fragment.
D/FlutterView(13747): Attaching to a FlutterEngine: io.flutter.embedding.engine.FlutterEngine@32f4f2a1
D/FlutterActivityAndFragmentDelegate(13747): Executing Dart entrypoint: main, and sending initial route: /
I/flutter (13747): Platform: Android
I/flutter (13747):
I/flutter (13747): *** Modular Routers ***
I/flutter (13747): / => SplashPage
I/flutter (13747): /login => LoginPage
I/flutter (13747): /cadUser => CadUserListPage
I/flutter (13747): /dashboard => DashboardPage
I/flutter (13747): /catalogo => CatalogoPage
I/flutter (13747): /cadUser/detalhes => CadUserEditPage
I/flutter (13747): /catalogo/detalhes => DetalhesPage
I/flutter (13747):
I/flutter (13747): *****
I/flutter (13747): -- AppModule INITIALIZED
E/flutter (13747): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Stack Overflow
�[38;5;248mE/flutter (13747): #0 Modular._getInjectableObject�[39;49m
�[38;5;248mE/flutter (13747): #1 Modular.get�[39;49m
�[38;5;248mE/flutter (13747): #2 Inject.get�[39;49m
�[38;5;248mE/flutter (13747): #3 AppModule.binds.�[39;49m
�[38;5;248mE/flutter (13747): #4 ChildModule.getBind�[39;49m
�[38;5;248mE/flutter (13747): #5 Modular._getInjectableObject�[39;49m
�[38;5;248mE/flutter (13747): #6 Modular.get�[39;49m
�[38;5;248mE/flutter (13747): #7 new UserModel�[39;49m
�[38;5;248mE/flutter (13747): #8 new _LoginControllerBase�[39;49m
E/flutter (13747): #9 new LoginController (package:meuapp/app/modules/login/login_controller.dart)
�[38;5;248mE/flutter (13747): #10 AppModule.binds.�[39;49m
�[38;5;248mE/flutter (13747): #11 ChildModule.getBind�[39;49m
�[38;5;248mE/flutter (13747): #12 Modular._getInjectableObject�[39;49m
�[38;5;248mE/flutter (13747): #13 Modular.get�[39;49m
�[38;5;248mE/flutter (13747): #14 new UserModel�[39;49m
�[38;5;248mE/flutter (13747): #15 new _LoginControllerBase�[39;49m
E/flutter (13747): #16 new LoginController (package:meuapp/app/modules/login/login_controller.dart)
�[38;5;248mE/flutter (13747): #17 AppModule.binds.�[39;49m
�[38;5;248mE/flutter (13747): #18 ChildModule.getBind�[39;49m
�[38;5;248mE/flutter (13747): #19 Modular._getInjectableObject�[39;49m
�[38;5;248mE/flutter (13747): #20 Modular.get�[39;49m
�[38;5;248mE/flutter (13747): #21 new UserModel�[39;49m
�[38;5;248mE/flutter (13747): #22 new _LoginControllerBase�[39;49m
E/flutter (13747): #23 new LoginController (package:meuapp/app/modules/login/login_controller.dart)
�[38;5;248mE/flutter (13747): #24 AppModule.binds.�[39;49m
�[38;5;248mE/flutter (13747): #25 ChildModule.getBind�[39;49m
�[38;5;248mE/flutter (13747): #26 Modular._getInjectableObject�[39;49m
�[38;5;248mE/flutter (13747): #27 Modular.get�[39;49m
�[38;5;248mE/flutter (13747): #28 new UserModel�[39;49m
�[38;5;248mE/flutter (13747): #29 new _LoginControllerBase�[39;49m
E/flutter (13747): #30 new LoginController (package:meuapp/app/modules/login/login_controller.dart)
�[38;5;248mE/flutter (13747): #31 AppModule.binds.�[39;49m
�[38;5;248mE/flutter (13747): #32 ChildModule.getBind�[39;49m
�[38;5;248mE/flutter (13747): #33 Modular._getInjectableObject�[39;49m
E/flutter (13747): ...
E/flutter (13747): ...
�[38;5;248mE/flutter (13747): #18149 ChildModule.getBind�[39;49m
�[38;5;248mE/flutter (13747): #18150 Modular._getInjectableObject�[39;49m
�[38;5;248mE/flutter (13747): #18151 Modular.get�[39;49m
�[38;5;248mE/flutter (13747): #18152 AppWidget._getDeviceID�[39;49m
�[38;5;244mE/flutter (13747): #18153 _AsyncAwaitCompleter.start (dart:async-patch/async_patch.dart:45:6)�[39;49m
�[38;5;248mE/flutter (13747): #18154 AppWidget._getDeviceID�[39;49m
�[38;5;248mE/flutter (13747): #18155 AppWidget.build�[39;49m
�[38;5;244mE/flutter (13747): #18156 StatelessElement.build�[39;49m
�[38;5;244mE/flutter (13747): #18157 ComponentElement.performRebuild�[39;49m
�[38;5;244mE/flutter (13747): #18158 Element.rebuild�[39;49m
�[38;5;244mE/flutter (13747): #18159 ComponentElement._firstBuild�[39;49m
E/flutter (13747): #18160 ComponentElement.mount (package:flutter/src/widgets/framework.dart:42
�[38;5;248m════════ Exception caught by widgets library ═══════════════════════════════════�[39;49m
�[38;5;244mThe following StackOverflowError was thrown building _DisposableWidget(state: __DisposableWidgetState#86548):�[39;49m
Stack Overflow
�[38;5;244mThe relevant error-causing widget was�[39;49m
�[38;5;248mMaterialApp�[39;49m
�[38;5;244mWhen the exception was thrown, this was the stack�[39;49m
�[38;5;244m#0 _LinkedHashMapMixin._getValueOrData (dart:collection-patch/compact_hash.dart:333:3)�[39;49m
�[38;5;244m#1 _LinkedHashMapMixin.containsKey (dart:collection-patch/compact_hash.dart:357:53)�[39;49m
�[38;5;248m#2 ChildModule.getBind�[39;49m
�[38;5;248m#3 Modular.get�[39;49m
�[38;5;248m#4 Inject.get�[39;49m
�[38;5;244m...�[39;49m
�[38;5;248m════════════════════════════════════════════════════════════════════════════════�[39;49m
Boa tarde, tem horas que mesmo saindo de um módulo, ele não tá executando dispose. Veja um exemplo de uma rota:
AppModule
List<Router> get routers => [
...
Router('/profile', module: ProfileModule()),
];
ProfileModule
@override
List<Router> get routers => [
Router('/', child: (_, args) => ProfilePage()),
Router('/edit', child: (_, args) => ProfileEditPage()),
Router('/about', child: (_, args) => ProfileAboutPage()),
];
No meu app, primeiro entra no ProfilePage pra exibir os dados, e exibe uma opção para exibir detalhes (/profile/about
) ou editar o perfil(/profile/edit
)... E pelo botão voltar que é colocado na AppBar, vai seguindo a stack das rotas até retornar pra tela anterior à carga do /profile
aqui o comportamento tá certinho... mas se tento navegar pra fora, com um pushReplacementNamed
, popAndPushNamed
etc, navega pro novo destino fora da rota /profile
mas não dá dispose no módulo.
Nesse caso eu devo forçar o dispose de alguma forma antes de navegar pra fora da rota ?
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.