Reputation: 5829
I'm creating an application using Aurelia, and in part of that application I have a grid that lists users, and specifically that users active status.
To allow the active state to be edited I've created a slide button control (Similar to those seen in iOS) where, sliding to the left is true, and to the right is false.
What I'd like to do is use this control in my user grid, so that people using it, can just click on the custom slide button to enable/disable the user, but I need that control to feed it's value when it changes back to the row it's placed in.
Something like this:
Imagine my table looks like this
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Is Active?</th>
</tr>
</thead>
<tbody>
<tr repeat.for="user of userList">
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.email}</td>
<td><slidebutton active="${user.active}"></slidebutton></td>
</tr>
</tbody>
</table>
This works great in so much that the slide button gets set to a default value based on the active status of the user as expected.
However when the slide button is changed, I would like for the row to be notified in someway, so that I can tell it to update the back end and change the status.
I'm not against passing in the user id to the custom component EG:
<td><slidebutton active="${user.active}" uid="${user.id}"></slidebutton></td>
But i'd rather not have the control make the call, or be doing anything that prevents me from using it in other places, such as on other grids that might have different items of toggle-able information.
I had thought of an event based way of doing it, then I looked at one of the user tables and saw there was a potential for a table with over 500 rows in it, and tracking/managing 500 events from 500 slide buttons didn't really seem like something I'd particularly want to do.
If there's a way of reflecting the value back into the attribute, then that I think would be a great start, but what I'd actually like if at all possible, is for the custom control to directly change the underlying view model on the row if at all possible.
Upvotes: 1
Views: 328
Reputation: 10887
You can easily set up two-way databinding. First off, you should probably switch over to using the .bind
syntax instead of using string interpolation to pass values in. This is because using string interpolation will convert your values to strings, while the .bind
syntax can preserve the type of whatever you are passing in. It also works for binding in objects and the such.
<td><slidebutton active.bind="user.active" uid.bind="user.id"></slidebutton></td>
We can change .bind
to .two-way
in the example code above, and this will tell Aurelia that these bindings need to be two-way. That will accomplish what you want, but it would be annoying to always have to do this:
<td><slidebutton active.two-way="user.active" uid.bind="user.id"></slidebutton></td>
Note that I only set the active
property to be two-way databound, as I'm guessing the uid
property isn't changed inside the slidebutton
control, and thus there's no need to do two way databinding on it.
But we can set this up to default to two-way databinding. Let's look at how to do this. I'm sure you've already created the bindable properties for active
and uid
in the slidebutton
custom element. I'm betting they look like this (in ESNext):
@bindable active;
@bindable uid;
If we add a bit of configuration to these, we can set these properties to default to two-way databinding, and then you'll get the two-way databinding that you seek by default.
@bindable({ defaultBindingMode: bindingMode.twoWay }) active;
@bindable uid;
Note that I'm using bindingMode.twoWay
above. You'll need to import this enum from the aurelia-framework
module. Thus, you might have something like the following line at the top of the slidebutton
's view model file:
import {bindable, bindingMode} from 'aurelia-framework';
Once you've done this, you can go back to using active.bind="user.active"
and Aurelia will handle the two-way databinding for you.
Upvotes: 5