如何确定刺激控制器的范围



比如说,我们有一个可以切换侧边栏的Stimulus控制器。不过,根据设备的不同,触发切换动作的按钮位于不同的位置。例如,当您在移动设备上时,在标题中;当您在桌面设备上时在主导航中。

在这种情况下你会怎么做?初始化两个Stimulus控制器(一个在属于标题的div中,另一个属于主导航(还是只初始化一个Stimulu控制器更好,例如在包含标题和主导航的包装器div标签中?

我会在body标签上放一个侧边栏控制器。

只要侧边栏控制器不被重用,它就完全没问题。它不适用于通用的切换控制器。

<body data-controller="sidebar">
<header class="sm:hidden">
<button data-action="sidebar#toggle">Toggle sidebar</button>
</header>
<section data-sidebar-target="sidebar">
Some content in the sidebar
</section>
<main>
<button class="hidden sm:inline-block" data-action="sidebar#toggle">Toggle sidebar</button>
</main>
</body>

我建议尽量避免使用范围过大的控制器。在DOM的很大一部分上有多个控制器可能会带来一些性能问题。

具有CCD_ 1&sidebar-toggle控制器将具有一个通用的"激发事件"控制器。

我们甚至可以从Alpine.js及其x-on指令中获得灵感。我们可以有一个范围较小的"on"操作do something类型控制器,让我们有一种通用的方式来触发任何事件。

HTML

让我们从HTML开始,类似于前面的答案,我们有一个侧边栏div,然后有两个按钮,它们基本上做相同的事情(触发事件(。

我们可以利用Stimulus与DOM事件协调的方法来帮助我们,但这次是使用名为'sidebar:toggle'的自定义全局事件。

请注意,侧边栏控制器使用@window侦听事件,以确保它在DOM上一直拾取任何"冒泡"事件。

https://stimulus.hotwired.dev/reference/controllers#cross-控制器与事件的协调

<body>
<header class="sm:hidden">
<button
data-controller="on"
data-action="click->on#go"
data-on-event-name-param="sidebar:toggle"
>
Toggle sidebar
</button>
</header>
<section data-controller="sidebar" data-action="sidebar-toggle@window->sidebar#layout">
Some content in the sidebar
</section>
<main>
<button
class="hidden sm:inline-block"
data-controller="on"
data-action="click->on#go"
data-on-event-name-param="sidebar:toggle"
>
Toggle sidebar
</button>
</main>
</body>

JavaScript(控制器(

Sidebar控制器将有您想要的任何东西,但也有一个toggle的方法,我们可以通过该操作触发它。

import { Controller } from '@hotwired/stimulus';
class Sidebar extends Controller {
static targets = [];
static values = { expanded: { default: false, type: Boolean } };
connect() {
// do the things
}
toggle() {
this.expandedValue = !this.expandedValue;
}
}

On控制器利用刺激动作参数能够接收DOM上设置的任何动态值作为其事件。

请注意,On控制器有意将事件设为气泡(这是默认值,但最好是显式的(,以便窗口上的任何其他事件侦听器都可以侦听此消息。

import { Controller } from '@hotwired/stimulus';
class On extends Controller {
go({ params: { eventName } }) {
this.dispatch(eventName, { prefix: '', bubbles: true, cancelable: false });
}
}

最新更新