Should store.push invalidate an entire model?


#1

I’m using store.push('encode', data) to update a model from a websocket event. I also have the following CP on an array controller:

activeEncodes: function() {
  return this.filterBy('model', 'isActive');
}.property('model.@each.isActive')

This CP is being recalculated each time store.push gets new data, even though isActive is not changing. This is causing some visual jank in my UI (#each is refiring).

Should this be happening? I would have expected it not to fire, but this answer to my SO question says push invalidates the whole model. Is that true?


#2

I use pushPayload to update data from websockets all the time and whilst I don’t know if this invalidates the whole array, I certainly don’t see any visual issues.

Have you tried using Em.computed.filter instead?


#3

I have, and am using this form to debug. From the docs it seems the observer shouldn’t fire just because some data has changed.

The visual issue comes from a popover being shown, and when the data changes, the array changes, so the entire DOM node is re-rendered causing the popover to disappear.


#4

Check out the bin here: http://emberjs.jsbin.com/ruwet/8/edit?html,js,console,output

I would think that array doesn’t need to be recalculated, but it is.


#5

You are explicitly recalculating the array. You have a property that depends on model.@each.isActive. Every time that happens, you return a new array, so this behaviour is expected. If you don’t want this behaviour, don’t return a new array, and use a reduceComputed macro as previously suggested, e.g. http://emberjs.jsbin.com/lobozihico/4/edit

I suspect this will solve it, if not then it may be something else I think


#6

But shouldn’t the method trigger (and thus recalculate) only if the model.@each.isActive observer fires? And shouldn’t that only happen if one of the model’s isActive property changes (or the collection changes)?


#7

I don’t think so, because the push will eventually call set and set isActive, so the observer will be triggered. However reduceComputed should solve your problem - have you tried it yet?


#8

Not yet, just want to make sure I understand.

How does @this work in the filterBy?


#9

@this seems to have solved it, thanks!


#10

Actually this is still not working. See here: http://emberjs.jsbin.com/loseda/3/edit?html,css,js,output

The whole array updates, and repaints the entire list. So you lose the users’s input state (for example).


#11

@alexspeller what do you think?


#12

I don’t know the answer, you could try updating the individual properties manually, using an itemController, or something else. This may be an ember data bug that you could report on github, but I’m not sure