-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
More specific notifications in observableArray #502
Comments
I just realized that a cleaner solution would be to have separate events on top of the existing events (such as "inserted", "removed", etc.). I like that a little better and will probably play around with it in my fork. |
This might be useful for you: http://jsfiddle.net/mbest/Jq3ru/ |
Awesome! Thanks! I'll definitely use this to get me unstuck, but observationally it seems like it would be a slower solution than adding more granular notifications. Of course, without measurements I'm not sure but I wonder if this is something you guys would be interested in despite the ability to work around it? Thanks again, if I get some time I might prototype this in my fork anyway, but for now, I'm unstuck! |
Yes, and please share with us whatever you do put together. |
I would also love to see more info added to the subscribe callback. I checked the ko.utils.compareArrays, used in mbests example, and it will add alot of complexity for large arrays with lots of changes. |
Hey, thanks for the suggestion. It's unlikely that we'd precompute diffs on arrays proactively just in case the subscriber wants that information, as it would be a significant new perf cost. However, subscribers can certainly make use of |
Thanks for feedback Steve. ko.utils.compareArrays is a solution offcourse, but it still has a lot of added complexity in worst cases above Ordo n^2 Im working on a Knockout Concurrency conflict resolver plugin and I would love this feature, check line 56 (extendObservableArray) |
No, it doesn't work like that. In general, when someone changes an observable array, they aren't pushing or removing items, they are simply replacing the entire observable array contents. The The design of observable arrays is such that there are no guarantees that when someone mutates the array, they will do it through the |
I'll have to look at the Knockout code, but to me all methods that mutates the array has knowledge about the items that did it (Add, AddRange, Remove, RemoveRange, etc). Even the mapping plugin uses push to update the array (Subscribe methods triggers as many times has you have items in the JSON data), in most CRUD apps you let the user remove / add items too. So I think push / remove is a very common scenario... |
It's common, but it's not guaranteed. Anybody can write an entirely new collection to an observable array at any time. |
Yupp, so the subscribe method should give you an array of items (the entire array), an array of removed items, and an array of added items. Thats my two cents atlest, but I haven't had time to look at the knockout source for the observableArray, I guess you do not publish the subscribe event from the mutation methods on the array? |
Sorry, it just doesn't work like that. In general, people can make arbitrary mutations without using specific methods like |
I still dont understand how you cant isolate the mutation methods and let them publish, but im sure you have good reasons, will go with the compareArrays for now, Thanks for your Help Steve! /Anders |
Hmm, since the subscribe method gives the actual array reference I cant save the old state beacuse the old state will be updated to the new state. Any way to solve this without cloning the array each time? ko.observableArray.fn.subscribeWithChanges = function(callback) {
var oldArray = null;
this.subscribe(function(items) {
var changes = ko.utils.compareArrays(oldArray, items);
var added = [];
var deleted = [];
ko.utils.arrayForEach(changes, function(item) {
switch(item.status) {
case "added":
added.push(item.value);
break;
case "deleted":
deleted.push(item.value);
break;
}
});
oldArray = items;
callback(added, deleted);
});
} |
Cloning is the only way to ensure they aren't the same array. The |
Yupp. it ended up being 40 slower than just doing n^2 :D |
If an array is already tied to a |
First, awesome, thanks for ko.utils.compareArrays() - you guys should put that on the the actual docs page about observableArrays! Its crazy that the only way to find out about this very useful tool is through this issue and a google group posting. I'd recommend also explaining why each subscribe event can't receive the change information or you're going to be fielding a ton of questions like the one from Anders above. Two, if in a particular case where someone interacts with an observableArray mostly through push/remove/splice, there is absolutely nothing stopping them from proxying those methods to run compareArrays behind the scenes and broadcast a different event. It should be all of...10 lines of code maybe? Finally, @mbest your jsfiddle is broken in chrome (probably others).
|
Now that #695 will be part of 3.0, does this issue still need to be open? |
Hey knockout crew.
I'm working with Knockout in a Windows 8 app and in order to properly bind to some WinJS controls, I need to be able to adapt ko observableArrays in to IListDataAdapter implementations. I'm totally fine with writing such an adapter myself but it's proving more difficult than I'd like due to the fact that observableArrays just fire a simple notification with the new array and it's up to me to figure out what actually changed. I'd like to propose the following change:
This 'changeInfo' data structure might look something like this for a push:
Or for a removeAll
Splices could either be a combination or a separate "type".
I don't really even need the removed/added/etc. item but I figured it would be useful data that the array has, the index alone would probably be sufficient.
Anyway, I'm happy to fork and work on this myself, but I don't want to spend a lot of time making this work inside KO if the core team isn't a fan of the idea (or if you have comments, I'd like to take them in to consideration before sending a PR).
Thoughts? If you guys really think this doesn't belong in KO, I can probably make it work by augmenting observableArrays myself, but I'd like to do something in the core to support this scenario :).
The text was updated successfully, but these errors were encountered: