Closed thencke closed 4 years ago
Hi, thanks for providing a reproduction code. Do you want each listTile to have its own controller instance? I think a global = false in your GetBuilder would solve that.
Hi, thanks for providing a reproduction code. Do you want each listTile to have its own controller instance? I think a global = false in your GetBuilder would solve that.
Exato, eu vou escrever em português mesmo não sabia que eras brasileiro também. Meu caso de uso é exatamente esse, eu tenho uma lista de widgets que precisam cada um ter seu próprio controller pra controlar o seu estado, só que me parece que o approach do Get visa ter um gerenciamento de estado no padrão "singleton", então eu não consegui instanciar mais de um controller sem dar esses problemas.
Tentei adicionar o global = false
pra fazer um teste, mas mesmo assim não funcionou, ocorre outro exception:
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following NoSuchMethodError was thrown building MyTile:
flutter: The method 'add' was called on null.
flutter: Receiver: null
flutter: Tried calling: add(Instance of 'RealState')
flutter:
flutter: The relevant error-causing widget was:
flutter: MyTile
lib/main.dart:19
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
flutter: #1 _GetBuilderState.initState
package:get/…/state/get_state.dart:92
flutter: #2 StatefulElement._firstBuild
package:flutter/…/widgets/framework.dart:4640
flutter: #3 ComponentElement.mount
package:flutter/…/widgets/framework.dart:4476
flutter: ... Normal element mounting (39 frames)
flutter: #42 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3446
flutter: #43 Element.updateChild
package:flutter/…/widgets/framework.dart:3214
flutter: #44 SliverMultiBoxAdaptorElement.updateChild
package:flutter/…/widgets/sliver.dart:1162
flutter: #45 SliverMultiBoxAdaptorElement.createChild.<anonymous closure>
package:flutter/…/widgets/sliver.dart:1147
flutter: #46 BuildOwner.buildScope
package:flutter/…/widgets/framework.dart:2607
flutter: #47 SliverMultiBoxAdaptorElement.createChild
package:flutter/…/widgets/sliver.dart:1140
flutter: #48 RenderSliverMultiBoxAdaptor._createOrObtainChild.<anonymous closure>
package:flutter/…/rendering/sliver_multi_box_adaptor.dart:354
flutter: #49 RenderObject.invokeLayoutCallback.<anonymous closure>
package:flutter/…/rendering/object.dart:1866
flutter: #50 PipelineOwner._enableMutationsToDirtySubtrees
package:flutter/…/rendering/object.dart:918
flutter: #51 RenderObject.invokeLayoutCallback
package:flutter/…/rendering/object.dart:1866
flutter: #52 RenderSliverMultiBoxAdaptor._createOrObtainChild
package:flutter/…/rendering/sliver_multi_box_adaptor.dart:343
flutter: #53 RenderSliverMultiBoxAdaptor.addInitialChild
package:flutter/…/rendering/sliver_multi_box_adaptor.dart:427
flutter: #54 RenderSliverList.performLayout
package:flutter/…/rendering/sliver_list.dart:79
flutter: #55 RenderObject.layout
package:flutter/…/rendering/object.dart:1767
flutter: #56 RenderSliverEdgeInsetsPadding.performLayout
package:flutter/…/rendering/sliver_padding.dart:135
flutter: #57 RenderSliverPadding.performLayout
package:flutter/…/rendering/sliver_padding.dart:375
flutter: #58 RenderObject.layout
package:flutter/…/rendering/object.dart:1767
flutter: #59 RenderViewportBase.layoutChildSequence
package:flutter/…/rendering/viewport.dart:452
flutter: #60 RenderViewport._attemptLayout
package:flutter/…/rendering/viewport.dart:1444
O código reproduzível desse erro é (embora talvez nem seja necessário, já que a unica coisa diferente é o global = false
no GetBuilder)
import 'package:flutter/material.dart';
import 'package:get/get.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
body: ListView(children: [
MyTile(cId: 'one'),
MyTile(cId: 'two'),
MyTile(cId: 'three'),
]),
),
);
}
}
class MyTileController extends GetController {
int counter = 0;
void increment() {
counter++;
update(this);
}
}
class MyTile extends StatelessWidget {
final String cId;
MyTile({Key key, this.cId}) : super(key: key);
@override
Widget build(BuildContext context) {
return GetBuilder(
id: cId,
global: false,
init: MyTileController(),
builder: (controller) {
return ListTile(
title: Text('My Counter Value is: ${controller.counter}'),
trailing: IconButton(onPressed: controller.increment, icon: Icon(Icons.add)),
);
},
);
}
}
Screenshot do exception: https://prnt.sc/sge6zw
De novo, parabéns pela lib, com certeza vai fazer parte de todos os meus projetos daqui pra frente, eu só estou relutante em trocar o mobx pelo modulo de gerência de estado do Get por causa desses probleminhas, assim que estabilizar aí sim entro de vez.
Mano, só tenho a agradecer, na penultima atualização, eu removi acidentalmente um '[]' da lista de ids de controladores não globais (provavelmente porque eu comentei o código acima, deve ter pegado junto) e gerou o erro, testa a versão 2.4.0 com global = false que vai funcionar normalmente.
Perfeito! agora sim está funcionando com um controller dedicado pra cada widget. Obrigado pela rapidez do update. Vou fazer mais uns estudos aqui pra ver se compensa eu refatorar a minha aplicação inteira que usa mobx pra passar a utilizar o Get.
Outra coisa, você pretende implementar algo na pegada do "reaction" do mobx? tipo quando certa variável alterar o valor é executado um evento dentro do controller. Vou fechar essa issue aqui, o problema foi resolvido, essa minha pergunta aí não condiz com o contexto da issue, se quiser eu abro uma nova isso de feature request.
Abraços
Perfeito! agora sim está funcionando com um controller dedicado pra cada widget. Obrigado pela rapidez do update. Vou fazer mais uns estudos aqui pra ver se compensa eu refatorar a minha aplicação inteira que usa mobx pra passar a utilizar o Get.
Outra coisa, você pretende implementar algo na pegada do "reaction" do mobx? tipo quando certa variável alterar o valor é executado um evento dentro do controller. Vou fechar essa issue aqui, o problema foi resolvido, essa minha pergunta aí não condiz com o contexto da issue, se quiser eu abro uma nova isso de feature request.
Abraços
Então, reaction com o Get tradicional não é necessária, porque toda alteração de uma variável depende de um set, e dentro desse set você pode chamar qualquer evento.
Com o GetX (lançado com o mesmo update do fix, mas ainda sem documentação), você pode dar listen em qualquer variável, e não precisa de reaction pra isso. ex:
final name = "JOÃO".obs;
name.listen((newName){ Get.snackbar("Tudo ok", "nome alterado com sucesso pra $newName"); });
name.value = "Pedro";
// snackbar abre
Implementei essa Api que é o meio termo entre o bloc e o mobx. Ela tem tudo que o mobx tem diretamente, sem precisar de gerador de codigo ou marcação, e tem a API do rxDart inteira disponível, se a pessoa quiser pegar o nome joão e adicionar outro nome no final sempre que mudar, ela pode. É todo poder de manipulação de streams do bloc, com a facilidade do MobX, sem gerador de código, mas obviamente, foi lançado hoje, ainda to criando os testes pra só lançar a documentação quando tiver redondo.
Hi, it's me again. I really like the Get's approach for state management, it's really simple and straightforward, but I encountered some problems when I tried to create a list (ListView) of widgets that instantiate a GetController for each one. Here's a reproducible snippet:
Note that, when you tap the + button, it increments the counter value for every widget. I even tried to shoot in the dark adding an Id to the GetBuilder, but does not work too.
I also tried this approach:
Instantiating the controller outside GetBuilder init, but this causes an exception to be thrown:
So, Is there a way to instantiate more than one controller of a type to achieve my goal? Btw, great library in general, I am thinking about getting rid of mobx and start using this, but this problem stopped me from continuing, because in mobx I can have several controllers attached to different siblings widgets and it works very well. Thanks in advance.