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

Tag.updateValue cannot write undefined back to the source #432

Closed johan-ohrn closed 4 years ago

johan-ohrn commented 4 years ago

See this fiddle for a repro. Watch the console and notice that it write out the old value.

Basically updateValue(undefined, index) does not write undefined back to the source.

BorisMoore commented 4 years ago

That is actually by design. (To change it would also be breaking). Currently if a tag control calls updateValue with the value undefined it is treated as a no-op. Generally you would expect user interactions with a control, for example, to be able to set bound data properties to any value, including falsey values (null, 0, false, "" ...) - but not to be able to set the value to undefined. (At least that is how I see it...)

So you can safely write code in your custom tag that does for example updateValue(a.b, ...) or updateValue(a[3], ...) and if a.b or a[3] are undefined it won't try to change the data property to undefined. If it did, that could raise other issues, and lead to unexpected bugs.

In fact this fits also with the fact that you can use tag.updateValues() to update multiple bindTo target values, but not all, by passing in undefined for those you don't want to modify:

tag.updateValues(a, b, undefined, c, d,...)

And it is similar to the treatment of convertBack, see: https://www.jsviews.com/#tagoptions@bindto where it says:

When the tag control is updating a bindTo target, then convertBack(val1, val2, val3 ...) will be called, with each argument undefined except for the argument that is updating.

See also references to undefined in this section: https://www.jsviews.com/#bindingpatterns@setvalue-updatevalue, where it says, about setValue() - and also talks of symmetry between setValue and updateValue:

Next, if the value (or the value returned by the handler if there is one) is not undefined, and if there are linked elements, it will set the value on the appropriate linked element.

That said, you can write code in your tag to directly do an observable setProperty("myprop", undefined), if that is really what you want....

johan-ohrn commented 4 years ago

Ah I understand. Thanks for the explanation. I was looking through the documentation on updateValue method but missed the setValue/updateValue chapter. I'll close this now.