BorisMoore / jsviews

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

itemVar is not created on new items in observable array #424

Closed BorisMoore closed 5 years ago

BorisMoore commented 5 years ago
{^{for items itemVar="~currentItem"}}{{:~currentItem}}{{/for}}
$.observable(items).insert(...)

For the inserted item, the item view does not have a ~currentItem. See stackoverflow.

BorisMoore commented 5 years ago

Here is a proposed fix:

jsviews1.0.4b.zip

alnico2001 commented 5 years ago

OP here... I tested jsviews1.0.4b itemVar="~currentItem" still is not updating after insert().

view.refresh(); didn't help either

Thanks

BorisMoore commented 5 years ago

Maybe you mean something different than I do, when you talk about itemvar updating after insert.

The behavior I am fixing is illustrated by the following which works with 1.0.4b but does not work with 1.0.3:

<script id="myTmpl" type="text/x-jsrender">
    {^{for items itemVar="~currentItem"}}
        {^{:#index}}
        {^{:name}}
        {^{:~currentItem.name}}
    {{/for}}
</script>

<div id="page"></div>

<script>
    var myTmpl = $.templates("#myTmpl"),
        data = {items: [{name: "Jo"}]};

    myTmpl.link("#page", data);

    $.observable(data.items).insert({name: "Jeff"});
</script>

Can you provide a small sample showing the behavior you are expecting to see, which fails with 1.0.4b?

alnico2001 commented 5 years ago

You are correct...1.0.4b does work for the immediate view. However, the inserted items itemVar="~currentItem" is not available/updated for nested contexts.

I add a nested {{for}} to your sample code:

{{for}}
     inNestedFor: {^{:~currentItem.name}}<br>
{{/for}}

When rendered I am expecting: inNestedFor: Jeff, but got: inNestedFor: Jo

<script id="myTmpl" type="text/x-jsrender">
    {^{for items itemVar="~currentItem"}}
        {^{:#index}}
        {^{:name}}
        {^{:~currentItem.name}}<br>

                {{for}}
                  inNestedFor: {^{:~currentItem.name}}<br>
                {{/for}}<br>
    {{/for}}
</script>

<div id="page"></div>

<script>
    var myTmpl = $.templates("#myTmpl"),
        data = {items: [{name: "Jo"}]};

    myTmpl.link("#page", data);

    $.observable(data.items).insert({name: "Jeff"});
</script>
BorisMoore commented 5 years ago

That's great - now I understand. I'll look into it...

BorisMoore commented 5 years ago

@alnico2001: OK - I have a fix which I believe addresses all the itemVar scenarios. Can you test it and see if you find any issues...

jsviews1.0.4c.zip

Thanks!

alnico2001 commented 5 years ago

Excellent! 1.0.4c works in all my tests. Thank you for your speedy fix!

Brent

BorisMoore commented 5 years ago

Thanks for calling this out. When I implemented the itemVar feature, I looked mostly at JsRender, and I missed some observable update scenarios... I've added new unit tests now to cover those scenarios...

BorisMoore commented 5 years ago

I have an update ready for publishing (1.0.4) that includes this fix. However I will be travelling for the next three weeks, and unfortunately did not quite have enough time to complete testing and committing the new version. I expect to do so in the first week of July.

alnico2001 commented 5 years ago

No problem Boris. Have a good trip.

BorisMoore commented 5 years ago

Fixed in v1.0.4