Closed lukaszdebowski closed 4 years ago
GetBuilder<UserController>(
id: 'name',
builder: (_) {
return Text("Full Name: ${_.value.fullName}");
},
),
GetBuilder<UserController>(
id: 'email',
builder: (_) {
return Text("Email: ${_.value.email}");
},
),
// update only name
void setFirstName(String newName) {
value.firstName = newName;
update(['name']);
}
// update only email
void setEmail(String newEmail) {
value.email = newEmail;
update(['email']);
}
// update name and email
void setEmailAndName(String newEmail,String newName) {
value.email = newEmail;
value.firstName = newName;
update(['email', 'name']);
}
Yeah I've found that one, but there is this little scenario: let's say I have 10 different listeners across the app and want 1 particular to not rebuild, it would require me to provide the 9 ids to all the other ones and list them inside my update()
?
Another issue with this approach is that I can't have multiple fields with the same ID
Thanks for the response though! Really appreciate the package and your work, it's great 👍
Hey As is written in docs, GetBuilder is part of the simple state manager, it was made to be simple and lightweight, and for simple tasks.
In your case, you want granular control over your widgets and which one will update and when.
In this case, you should use the reactive state management, it have awesome features and let you have a lot of control of state. Following your example, in reactive state would be like this:
class UserController extends GetxController {
static UserController get I => Get.find();
final user = User( // changed the variable name to user
id: 0,
firstName: "John",
lastName: "Smith",
email: "john.smith@gmail.coim",
).obs; //make the user class observable
void setFirstName(String newName) {
// now instead of access the user class directly, you use `user.value` to access its values and update
user.value.firstName = newName;
// call update() is no longer needed
}
void setEmail(String newEmail) {
user.value.email = newEmail; // same here, using user.value
// call update() is no longer needed
}
}
in your view:
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text("Dashboard Screen"),
GetX<UserController>(
builder: (controller) {
return Text("Full Name: ${controller.user.value.fullName}"); // using `user.value` here too
},
),
GetX<UserController>(
builder: (controller) {
return Text("Email: ${controller.user.value.email}"); // same here
},
),
],
),
This way, automatically only the changed widget will be rebuilt, and you don't need to use identifiers for each update
Yeah I've found that one, but there is this little scenario: let's say I have 10 different listeners across the app and want 1 particular to not rebuild, it would require me to provide the 9 ids to all the other ones and list them inside my
update()
?Another issue with this approach is that I can't have multiple fields with the same ID
Thanks for the response though! Really appreciate the package and your work, it's great
You would only need to provide a single ID for the one you do NOT want to rebuild, and then it will only be rebuilt when the update is called with your ID. I recommend for this case the approach above @Nipodemos. Nothing prevents you from using simple management, but definitely if you need a complex solution, there is something better and reactive ready to use.
I would go as far as make it far more optimal...
Widget build(BuildContext context) {
return GetBuilder<SignInController>(
global: false,
init: SignInController(),
builder: (controller) {
someWidgetsHereThatUseTheSameController...
}
);
}
And then just have a single fieldWidget that handles each formfield.
As the existing tools for this resource were pointed out, and the issue was no longer answered, I am closing this issue.
@jonataslaw +1 for selector GetX and Obx are easy in use but heavily ram-consuming. GetBuilder is the fastest. Also, it would be easier to transfer the existing Provider-based project to Get. Ids / tags assignment looks like an antipattern, because it makes your widgets and controllers tightly coupled - you MUST add the same tags in your GetBuilders, which are listed in corresponing update([...]). Normally, controller shouldn't know anything about widgets and their tags, it should care about business logic only. It's better to let widgets to choose on which variables change they should rebuild.
@jonataslaw +1 for selector GetX and Obx are easy in use but heavily ram-consuming. GetBuilder is the fastest. Also, it would be easier to transfer the existing Provider-based project to Get. Ids / tags assignment looks like an antipattern, because it makes your widgets and controllers tightly coupled - you MUST add the same tags in your GetBuilders, which are listed in corresponing update([...]). Normally, controller shouldn't know anything about widgets and their tags, it should care about business logic only. It's better to let widgets to choose on which variables change they should rebuild.
GetBuilder has a filter
property where you can filter rebuilds.
I've just checked out filter
property. I can't find how exactly it filters rebuilds. It just does setState
on any change!
You can set any filter function, but seems like GetBuilder doesn't use it anywhere.
I compiled a minimal reproducible example, and can confirm that filter
actually works. Just wanted to make sure.
But it some kind of GetX magic, I can't understand the exact mechanism how the filters work.
Without filter - all 3 widgets print "rebuilt" With filter - only widget I clicked prints "rebuilt"
Is your feature request related to a problem? Please describe. Sometimes, when we call the
update()
method inside the controller, someGetBuilder
get rebuild unnecessarily, i.e let's say we have aUser
class withname
andemail
fields.This is our controller:
Then somewhere inside our view, we have something like this:
Even if we only use the
setFirstName
method on the controller, theemail
builder will rebuild (even though the email did not change).Describe the solution you'd like It would be nice to have something like a
select
property on theGetBuilder
widget, which is basically a function that returns the value, that must be changed inside our controller, for the builder to get rebuild. So something like:This would mean that only if the
email
field is different than it was before theupdate()
call, this builder should get updated.Describe alternatives you've considered Could't really find anything that would supply me with this functionality, but I could've searched wrong. Maybe there is something like that already?