cleanup not called when updating/refreshing
Hey, I have found an issue that cleanup will not be called though a component will be removed from the tree and replaced with a new one (same type but new instance)
please have a look at some sample code: http://jsfiddle.net/BsUDE/9/
In the output it should be 1,2 not 0,2
this can cause leaking of resources (eg if I would setInterval in the component)
Hey, Found out what's really happening
It will just call update and not create a new instance of inner component
checked what happens if component would change and it cleans the previous one though im my apps case the problem was the name of the component would be the same since I used a wrapper function, see: http://jsfiddle.net/BsUDE/12/
So the problem is you're swapping out components, but since they have the same ID, it doesn't actually swap them?
Yes it would appear so, the reason for this in my case is that I have a wrapper function around my components
Also this will be the same for browsers that don't have function.name even if you don't use a wrapper see: https://developer.mozilla.org/pl/docs/Web/JavaScript/Reference/Global_Objects/Function/name
probably better way of comparing would be to check if it is the same function using === if I have time ill try to create a pr for this
Managed to solve it another way, when I'm using my wrapper instead of just wrapping my component factory I wrap the whole array and set the key property to unique id of the view, now everything works perfectly
Yes, setting the key property will work. That's how I've been doing it. I'm still concerned about the original issues that bit you though.
I could solve this with a WeakSet of WeakMap, but that would change the minimim requirements for JavaScript significantly. (The idea is to store a weak list of all seen constructors and give each a unique ID so that they can be serialized to a string for the id algorithm.)
The way I am thinking now would be sufficient is something like:
//define this somewhere
var constructorIdProperty = Symbol ? Symbol('domchangerId') : '_domchangerId';
//maybe just '_domchangerId' to allow users to overwrite it?
var viewId = 1;
//get the id or create one (assuming component is the factory function)
var id = component[constructorIdProperty];
if(!id) {
id = component[constructorIdProperty] = "View" + viewId++;
}
(didn't run this so might not work)
This would allow the property to be hidden and not need more deps
Ok, so stick a property on the constructor. I suppose that would work, it's just messy to annotate passed in values directly. But as you say, this does work without weakmaps.
I don't think it is actually that bad since all browsers except IE have basic Symbol implementation so the value will not clash with anything and will be hidden from the user, though WeakMap would be nicer
only problem that can happen potentially is if someone iterates over properties of the constructor in IE and expects the value not to be there, though this can also be fixed by defining a non-enumerable property
Sounds good, want to send a PR?
sure, won't have time today, might do tomorrow though