BorisMoore / jsviews

Interactive data-driven views, MVVM and MVP, built on top of JsRender templates
http://www.jsviews.com/#jsviews
MIT License
856 stars 130 forks source link

Weird data-linked `for` loop behaviour with deep observing after model update #406

Closed trueqbit closed 5 years ago

trueqbit commented 6 years ago

I have a model representing settings, with an array nested in an object property of that model.

var settings = {
  nodes: {
    list: [],
  },
};

The template responsible for displaying the array uses a for-loop and is additionally listening to deep changes.

{^{for settings.nodes^list}}
{{/for}}

The UI offers the possibility to refresh or save the model, in which case all properties of the model get updated observably with the new data returned from a server.

$.observable(settings).setProperty(newSettings);

Now, whenever the list is made empty after updating the model - either by the server returning an already empty array, or by removing all items manually - then the loop behaves in a strange way: when adding a new array item, jsviews inserts 2 (two) list elements instead of one. Additionally the two items are interlinked - they show the same content and are both removed when removing one. This interlinked state gets broken up by clicking 'add' a second time.

Here is a fiddle showcasing the issue.

BorisMoore commented 6 years ago

Thanks Klaus - yes, thanks for reporting this. I started looking at it. I'll follow up further when I have more time - during next week some time, I think....

BorisMoore commented 6 years ago

This was very helpful in uncovering a couple of slightly obscure and hidden bugs. I have a fix within my current version of the next update. You can try it here: jsviews.js.txt

Let me know if it works for you, or if you see other issues.

trueqbit commented 6 years ago

Hi Boris, thank you for taking a look at this. The next update version is working good as far as I can tell - this specific issue is gone! Do I need to look out for something else?

Unless you put the fix up soon, would it be possible to get a minified version as well?

BorisMoore commented 6 years ago

No - no need to search for other issues. Just let me know if you see anything. Here is the minified version: jsviews.min.js.txt

trueqbit commented 6 years ago

Hi Boris, just recognised that something with the for/range tag is broken since v0.9.91g (Beta). The range tag behaves as if it loops over i = start; i < end; ++i instead of i = start; i <= end; ++i, i.e. the last value doesn't make it. See this fiddle

BorisMoore commented 6 years ago

Hi Klaus, yes, thanks for communicating on that...

That is in fact because the {{for}} tag now natively supports the range features. See https://github.com/BorisMoore/jsviews/issues/398#issuecomment-382913470.

The new behavior (with {{for}}) steps through values > start and < end, following the same semantics as the javascript array.slice() function.

Here is what you would need to do in your fiddle to go from 0 to 23.

This will be documented with the next update...

trueqbit commented 6 years ago

Thanks Boris - changing end to a kind of sentinel is actually an important (because breaking) change ... No worries, though, it's again working as expected!

BorisMoore commented 6 years ago

Yes, it will be called out as breaking. In fact the range tag was a sample, and will go away. The new features of {{for}} go beyond the range features, and you can do for example {{for items start=-4 end=-1}} to output the 4th to last item up to the next to last item..., or {^{for start=-4 end=-24 step=-1}} to generate an array going from -4 down to -23.

BorisMoore commented 5 years ago

This has been fixed in release v0.9.91.