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

After DOM modifications to the child options of a data-linked select, the first option shows as selected #398

Closed Mytia closed 5 years ago

Mytia commented 6 years ago

here is fiddle: https://jsfiddle.net/nq4372t8/30/

BorisMoore commented 6 years ago

I'm not sure what the problem is here. What behavior were you expecting? What do you mean by "after internal changes"?

BTW you need to use type="..." on your script block for declaring the template, or the browser will try to run the template contents as javascript.

Also, you have two version of jsviews loaded in your jsfiddle: 86 and 90...

Mytia commented 6 years ago

https://jsfiddle.net/nq4372t8/36/ I remove one of jsviews library, and fix type of template. But the problem is, that after change array of items views show that name is "1", but in object it is null. I expect that both select shows empty, beacuse name and name2 is null.

BorisMoore commented 6 years ago

Ah, got it, thanks! Yes, that is a (small) bug. I have a possible fix. I'll keep you posted...

BorisMoore commented 6 years ago

@Mytia: I have a candidate update which includes a fix for this issue, here: jsviews.js.txt

Would you be able to test it for your environment? Let me know if you see any issues. Thanks!

Mytia commented 6 years ago

I tested the new version in one of my projects and faced the following problems:

  1. create local variable with name ~tagCtx inside tag templete, fixed by renaming in my code
  2. problem with helpers that calls with data-bound, example: {^{:~test(1)}}, after this $.views.helpers.test is not a function

but all works fine in jsviews.90

BorisMoore commented 6 years ago

Excellent - very helpful. I'll get you an update tomorrow probably, which should correct 2).

You don't mention the <select> behavior, so I take it that the fix worked for you as far as that issue is concerned...

BorisMoore commented 6 years ago

Here is an update: jsviews.js.txt.

Let me know if this resolves issues. (You will still need to change your local variable name from ~tagCtx, since that is now a built-in helper, so a reserved name for a helper or contextual parameter.)

BorisMoore commented 6 years ago

@Mytia - let me know if you are able to test this in your environment. If you haven't got to it yet, you can use this even more recent version: jsviews.js.txt. Thanks!

Mytia commented 6 years ago

With new version everything works fine. Thanks

BorisMoore commented 6 years ago

Great. Thanks for testing!

Mytia commented 6 years ago
<div id="main"></div>

<script id="tmpl" type="text/x-jsrender">
  <select data-link="name">
    <option value="">Not selected</option>
    {^{for items}}
      <option>{^{>#data}}</option>
    {{/for}}
  </select>
  {{:name}}
</script>

<script>

var data = {
    name: 4,
    items: [1,2,3],
    items2: [4,5,6]
};

$.templates("#tmpl").link("#main", data);

$.observable(data).setProperty('items', data.items2);

</script>

I found another problem with new version: variable name has value 4, but when I replace items with items2 which contains '4' select doesn't refresh

Mytia commented 6 years ago
<div id="main"></div>

<script id="tmpl" type="text/x-jsrender">
  <select data-link="{:name:backConverter}">
    <option value="">Not selected</option>
    {^{for items}}
      <option>{^{>#data}}</option>
    {{/for}}
  </select>
  {{:name}}
</script>

<script>

$.views.converters({
  backConverter: function (value) {
    return value
  }
});

var data = {    
    name: '4',
    items: []
};

$.templates("#tmpl").link("#main", data);

$.observable(data.items).insert(0, [4,5,6]);

</script>

And another example: backConverter and insert in items array

BorisMoore commented 6 years ago

Thanks very much for calling those issues out. Very helpful!

Yes, I see them, and have a proposed fix. I'll provide it to you once I have tested/verified a bit more.

BorisMoore commented 6 years ago

Hi Mytia - here is an update (which includes quite a few other changes and fixes for the next update) with fixes for your issues. Let me know if you still see problems. Thanks!

jsviews.js.txt

Mytia commented 6 years ago

As I see one example works fine, but example with backConverter still doesn't work... But, if I understand right, it did not work correctly in versions 89-90 too.

BorisMoore commented 6 years ago

Ah - I had fixed the second scenario but when using both a converter and a back converter, not just a back converter on its own. (Which is an unusual scenario, since if you convertBack to a different format you would generally need to have convert do the inverse transformation.)

At any rate, here is an update which should work also for convertBack on its own: jsviews.js.txt

Mytia commented 6 years ago

Yes, my code also uses both converters:) Now this example works fine. But.. I found anouther problem after last changes: tag "range" from jsviews.com shows only 2 3 4 5, but should 1 2 3 4 5 in this example. The problem has appeared in the last two versions.

<div id="main"></div>

<script id="tmpl" type="text/x-jsrender">
  {^{range start=1 end=5}}
    {{:#data}}
  {{/range}}
</script>

<script>
$.templates("#tmpl").link("#main", {});
</script>
BorisMoore commented 6 years ago

Thank you again Mytia!

Yes, that is because in these new versions I am working on built-in support for sorting, filtering and range, when using the {{for}} tag on an array. So range becomes in effect native to the {{for}} tag, and you no longer need a custom range tag. But I had not yet rewritten the range samples to work correctly with this built-in behavior. When I have done so I'll let you know, and probably post you the update here.

BorisMoore commented 5 years ago

This has been fixed in release v0.9.91.