vanjs-org / van

🍦 VanJS: World's smallest reactive UI framework. Incredibly Powerful, Insanely Small - Everyone can build a useful UI app in an hour.
https://vanjs.org
MIT License
3.77k stars 87 forks source link

It doesn't work. Did I do something wrong? #232

Closed iuroc closed 8 months ago

iuroc commented 8 months ago

I put the State object created by van.state into a unified storage object, but when I use it, it doesn't work. Did I do something wrong? 1704896313954 1704896313961 1704896313970 image

iuroc commented 8 months ago

I think a possible issue could be related to the Bootstrap modal, such as it blocking relevant events. Is that a possibility?

I've tested in other locations and outside the modal, and found that there are no issues. The state responds normally.

iuroc commented 8 months ago

这个是正常的,关闭了模态框的 fade:

(注意 2 个视频需要下载到本地进行播放)

https://github.com/vanjs-org/van/assets/61752998/491e7e65-a530-4295-9bb5-e60d86c86623

下面是加上 fade:

image

发现失效了:

https://github.com/vanjs-org/van/assets/61752998/2351e120-158e-4980-82b9-ec228388d354

Tao-VanJS commented 8 months ago

It seems as a Bootstrap Modal related issue. Do you have a link to your code that has the problem?

iuroc commented 8 months ago

@Tao-VanJS The following example encounters the same issue, seemingly related to elements not being loaded into the document tree or being affected by asynchronous operations:

import van from 'vanjs-core'

const { button, div } = van.tags

const value = van.state('Hello World')

const app = div(
    div(value),
    button({
        onclick() {
            value.val = 'New Text'
        }
    }, 'Change Text')
)

setTimeout(() => {
    van.add(document.body, app)
}, 1000)
iuroc commented 8 months ago

This is similar to the issue with Bootstrap Modal. The new Bootstrap.Modal(HTMLDivElement) does not automatically add the element to the document.body. Instead, it is automatically added to the body when Modal.show() is executed, but only if the element doesn't exist in the body already. If the element is added to the body beforehand, it won't be automatically added again.

iuroc commented 8 months ago
const modalEle = div({ class: 'modal' })
const modal = new Modal(modalEle)
console.log(document.querySelector('.modal') == null)  // true
sirenkovladd commented 8 months ago

@iuroc, this is related to the internal work of garbage collection, you can read more here https://vanjs.org/advanced#avoid-your-bindings-to-be-gc-ed-unexpectedly

Here's a fixed example

import van from 'vanjs-core'
const { button, div } = van.tags

const value = van.state('Hello World')

const app = () => div(
    div(value),
    button({
        onclick() {
            value.val = 'New Text'
        }
    }, 'Change Text')
)

setTimeout(() => {
    van.add(document.body, app())
}, 1000)
iuroc commented 8 months ago

Yes, I also noticed this. VanJS performs garbage collection after 1000ms of adding _bindings, as demonstrated in the video below. Therefore, in the future, I should be mindful that when creating DOM elements through van.tags.*, they should be added to the DOM tree synchronously during their construction process to prevent them from being collected. Thank you for your assistance!

https://github.com/vanjs-org/van/assets/61752998/53e19418-3ffd-4249-8d20-95b3e8431a9a

Here is the code example from the video, and I think I understand how to address it:

import van from 'vanjs-core'

const { button, div } = van.tags

const value = van.state('Hello World')

const app = div(
    div(value),
    button({
        onclick() {
            value.val = 'New Text'
        }
    }, 'Change Text')
)
console.log((<any>value)._bindings[0])
setInterval(() => {
    console.log((<any>value)._bindings[0])
}, 100)

van.add(document.body, button({
    class: 'btn', onclick() {
        van.add(document.body, app)
    }
}, 'Click Me'))
iuroc commented 8 months ago

@Tao-VanJS The following example encounters the same issue, seemingly related to elements not being loaded into the document tree or being affected by asynchronous operations:

import van from 'vanjs-core'

const { button, div } = van.tags

const value = van.state('Hello World')

const app = div(
    div(value),
    button({
        onclick() {
            value.val = 'New Text'
        }
    }, 'Change Text')
)

setTimeout(() => {
    van.add(document.body, app)
}, 1000)

If I change it to setTimeout(() => { van.add(document.body, app) }, 999), it will work fine. However, this is just for testing and learning purposes, and it's not recommended for real-world use.