@Snapey I respectfully disagree. It’s only not possible if you are using a design pattern that in my opinion is flawed and I think using a table is the perfect example of this. Let’s use a simple example with all of your users that lists their name, email, a button to grant admin status, and a button to delete. Let’s also ignore the practicality that it is an admin function you wouldn’t have to be as security conscious about user input, but it will make due for the purposes of an example here.
Single God Component design:
You have one component that is responsible for displaying the table, filtering/searching/sorting, pagination, taking a user id to change role, taking a user id to delete.
Downsides:
- You have to hard code the user id into the html to be able to pass the id back to the component for changing the role or deleting. Easily manipulated client side, impossible to not expose database id’s to the client.
- Every round trip to the server for that component, you are reaching into the database to query all users.The component is keeping track of a collection of records, but you are still reaching into the database again to manipulate a single record.
Upsides:
- Less client side memory usage.
Parent Component for table structure, Child Components for each user model (each table row):
You have one component that is responsible for displaying the table, filtering/searching/sorting, pagination. You have multiple children components that each own a model, responsible for changing the role and deleting.
Downsides:
- Higher client side memory usage, comparatively.
Upsides:
- Only one database query for the individual record when the component is hydrated to change the role or delete. (Technically deleting adds an additional query to both designs). You can also fake the row rendering so you don’t need to have the parent query all users again to refresh the table showing that the user no longer exists.
- Quicker request round trip time when making changes to a model because of database speed, and you are only re-rending one table row, not the whole table.
- Parent component only queries and re-renders for multiple users when filtering, changing page number, change sorting order, not every action.
- Your
wire:click
s are only a method name, no parameters hard coded into the html of the page, or accepted by your methods on the component backend, so there’s nothing to be tampered with. If you know where to look (and aren’t hiding it), you can try, but livewire will error out.
- It’s completely possible to hide the model, all together from the client, server side. (Can lead to higher temporary server side memory usage, but that’s another topic.)
Comparing the two, I just see the first way is a bad design pattern. The second is more efficient with database queries and request sizes, you aren’t introducing an additional avoidable security opening that you now to also have to protect against - creating more work and code to maintain, and it adheres to the single responsibility principle a whole lot closer that the first way does. Unless there’s something I’m just blatantly missing, the pros far outweigh the cons of going with the second pattern.
I have yet to come across any reason to pass a method a parameter within the html. Anything that takes a user input can be modeled to a property, and if you cant accept input that way, you shouldn’t be accepting it as a method parameter on a livewire public method in the first place.