mbest / knockout-repeat

REPEAT binding for Knockout
http://mbest.github.io/knockout-repeat/
131 stars 18 forks source link

Handling Observable Arrays #3

Closed adamswallows closed 12 years ago

adamswallows commented 12 years ago

Is the plugin meant to handle observable arrays as they change - other than calling the remove / push methods?

When adding new items (push), the markup gets updated and same goes for remove. However, when I reset the observable with a new array (data coming back from the server), nothing gets updated.

This may be a separate issue, but I've also noticed when using "push" on the observable array, my custom bindings "update" method gets called without fail, but on "remove", it does not. Is this the intended behavior?

Any help would be appreciated. Thanks for the plugin - it's quick!

mbest commented 12 years ago

Yes, it's meant to handle observable arrays. I posted an update a few weeks ago that fixed some problems when using observable arrays, so please make sure you're using the latest version.

I'm really not sure why you're seeing these problems. Perhaps if you include the relevant code, or better yet, if you can reproduce the problems using jsfiddle, I can better help you solve them or identify a possible bug in the plugin.

adamswallows commented 12 years ago

Thanks for the quick reply. I am using the latest version from GitHub. I've created a fiddle to show the problems... Thanks for the help!

http://jsfiddle.net/aswallows/a2GFq/10/

mbest commented 12 years ago

Thanks for the example.

  1. repeat will not generally see changes you make by replacing the value of the property, you must set the value of the observableArray instead.
  2. It seems that remove doesn't work properly if you pass it an observable. This is probably a bug in Knockout. You can work around it by calling removeAll and passing the value to remove as an array.

Here's an update to your example with these changes: http://jsfiddle.net/a2GFq/12/

mbest commented 12 years ago

Your custom binding doesn't access or unwrap the $item and so doesn't see any updates. So it's only getting called when the length of your array increases (and so a new list item is added).

In this update, I've changed the binding to customBinding: $item() which unwraps the value and creates a subscription for your custom binding. Now it will be called for each item in the list whenever the array updates.

This may be a separate issue, but I've also noticed when using "push" on the observable array, my custom bindings "update" method gets called without fail, but on "remove", it does not. Is this the intended behavior?

mbest commented 12 years ago

In this update

Sorry, here is the updated example: http://jsfiddle.net/a2GFq/13/

adamswallows commented 12 years ago

These changes make sense and work well. Thanks again for the quick feedback!

mbest commented 12 years ago

Thanks again for the quick feedback!

You're welcome.

Something else I noticed (and this might not apply to your actual code) is that if you're removing the last item in an array, the fastest way to do so is using pop: http://jsfiddle.net/a2GFq/16/ Also if you know the index of the item you want to remove, you can use slice: myArray.slice(index, 1).