Open creatormir opened 6 months ago
This seems like a tricky bug in VanX. Handling the length
property of reactive arrays is always tricky. I am planning to get this bug fixed as soon as possible.
In the meantime, you can use items.arr = items.arr.slice(0, -1)
instead of items.arr.pop()
, which is currently working, as you can preview here: https://jsfiddle.net/w1bfpnzq/1/.
Now I got the problem that vanX.list does not work as I expect https://jsfiddle.net/creatormir/sqnxt0c6/4/
const {a, button, div, input, span, strike} = van.tags
let items;
const TodoList = () => {
items = vanX.reactive({arr:[0,1,2,3,4,5,6,7,8], n:555})
van.derive(() => {
console.log(items.arr.length, items.arr );
if (items.arr.length == 0) {
items.n = 987; // unattainable
}
} )
return vanX.list(()=>div( items.n), items.arr , (el, deleter, index) =>{
console.log('vanX.list', index);
return div(el);
});
}
van.add(document.body, TodoList());
console.log('\n\n');
items.arr.shift() // vanX.list reload list
items.arr.pop() // vanX.list reload list
items.arr.push(9)
items.arr = items.arr.slice(0, -1); // no reload vanX.list
items.arr = items.arr.slice(0, -1); // no reload vanX.list
items.arr = items.arr.filter((item, idx, array) => idx != 1); // no reload vanX.list # remove elem by idx ~ .splice(idx, 1)
If you're using vanX.list
, you should use vanX.replace
instead of directly reassigning the value.
Thank. This helped, I wrote vanX.replace(items.arr, l => l.filter((item, idx) => idx != 2));
it would be great if vanX.replace
returned true if there were changes
let changeCheck = vanX.replace(items.arr, ln => ln.filter(item => item != findValue) );
When using vanX.replace
, the original object is not changed (values from the array are not removed). Do I need to remove them separately? In this case, will me need to disable tracking on vanX.list
?
When using vanX.replace, the original object is not changed (values from the array are not removed).
I am not sure what you meant here. When using vanX.replace
, the items that don't appear in the new list will be removed (together with the corresponding UI elements).
Yes, indeed, this problem does not exist now, I forgot to update vanX. However, I noticed that deleter()
creates empty cells rather than removing them from the array. To fix this problem, need to repair the array vanX.replace(items.arr, l => l);
https://jsfiddle.net/creatormir/sqnxt0c6/11/
I'm exporting the latest versions, it would be nice to have a van.verion
command to know which version is loaded.
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/vanjs-org/van/public/van-latest.nomodule.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vanjs-ext@latest/dist/van-x.nomodule.js"></script>
However, I noticed that deleter() creates empty cells rather than removing them from the array.
This is intended behavior. By allowing "holes" in the array, we don't have to do lots of DOM updates whenever an item is deleted. Basically, you can control when to do the compaction with vanX.replace(items.arr, l => l)
while acknowledging that lots of DOM updates will be underway.
I don’t understand well, but what is the logic in leaving empty cells in the array? To fill them or what to do with them? Leave empty until better times? :-)
How can I disable Proxy?
I create a reactive object, make changes to it, and then move it to another array of another reactive object. It is necessary to break the connection between objects. Now I do it like this: mainObj.items.push( JSON.parse(JSON.stringify(newItem)) )
UPD: solution (not helped)mainObj.items.push( {...emptyItem} )
I don’t understand well, but what is the logic in leaving empty cells in the array? To fill them or what to do with them? Leave empty until better times? :-)
We leave cells empty until better timing. Let's say we have a reactive array [1, 2, 3, 4, 5]
, and the 3rd item is deleted by the user.
If we allow empty cells, the array will become [1, 2, empty, 4, 5]
. From the perspective of DOM tree, only the 3rd DOM element needs to be removed.
If we don't allow empty cells, the array will become [1, 2, 4, 5]
, then we need 3 DOM updates:
It is necessary to break the connection between objects.
To clarify, by breaking the connection, do you mean to avoid the detection of dependency from one reactive object to another reactive object? Do you have the full piece of code to illustrate your use case?
How to increase the precision of arr.length in van.derive? Currently length == 0 is not possible.
Hi @creatormir,
FYI, VanX 0.2.5 was just released which fixed the issue of array length binding.
Your example is now working in jsfiddle: https://jsfiddle.net/odr2nc5x/1/
Thank you so much for reporting the bug!
@all-contributors please add @creatormir for bug
@Tao-VanJS
I've put up a pull request to add @creatormir! :tada:
I don’t understand well, but what is the logic in leaving empty cells in the array?
@creatormir, one caveat is that because holes might exist in the array, the length
property isn't always the number of items in the reactive array. To reliably get the number of items in the array, you should use Object.keys(items).length
instead. I am planning to add this caveat to https://vanjs.org/ website as well.
We leave cells empty until better timing.
That is, doing this is incorrect (not effective)?
deleter(); // create empty cell
vanX.replace(items.arr, l => l); // for repair array
//...
van.derive(() => {
placeholder.hidden = items.arr.length > 0 ;
} );
It's effective to do this?
van.derive(() => {
placeholder.hidden = items.arr.filter(v=>v).length > 0 ;
} );
or
van.derive(() => {
placeholder.hidden = Object.keys(items.arr).length > 0 ;
} );
It's effective to do this?
van.derive(() => { placeholder.hidden = items.arr.filter(v=>v).length > 0 ; } );
or
van.derive(() => { placeholder.hidden = Object.keys(items.arr).length > 0 ; } );
Both of the approaches work. The 2nd approach (Object.keys(items.arr).length > 0
) might need less computation in theory.
@creatormir, FYI, the caveat was added to VanJS website: https://vanjs.org/x#caveat-array-holes.
How to increase the precision of arr.length in van.derive? Currently length == 0 is not possible.
https://jsfiddle.net/creatormir/cbaey9n3/