跳至内容

出口

出口允许你通过使用 CSS 选择器从另一个 Stimulus 控制器中引用 Stimulus 控制器实例及其 控制器元素

使用出口有助于跨控制器通信和协调,作为在控制器元素上分发自定义事件的替代方案。

它们在概念上类似于 Stimulus 目标,但不同之处在于它们引用 Stimulus 控制器实例及其关联的控制器元素。

<div>
<div class="online-user" data-controller="user-status">...</div>
<div class="online-user" data-controller="user-status">...</div>
...
</div>

...

<div data-controller="chat" data-chat-user-status-outlet=".online-user">
...
</div>

虽然目标是其自身控制器元素范围内的特定标记元素,但出口可以位于页面的任何位置,并且不一定必须在控制器范围内。

属性和名称

data-chat-user-status-outlet 属性称为出口属性,其值为 CSS 选择器,你可以使用它来引用其他控制器元素,这些元素应该作为出口在主机控制器上可用。主机控制器中的出口标识符必须与目标控制器的标识符相同。

data-[identifier]-[outlet]-outlet="[selector]"
<div data-controller="chat" data-chat-user-status-outlet=".online-user"></div>

定义

使用 static outlets 数组在你的控制器类中定义控制器标识符。此数组声明哪些其他控制器标识符可以用作此控制器上的出口

// chat_controller.js

export default class extends Controller {
static outlets = [ "user-status" ]

connect () {
this.userStatusOutlets.forEach(status => ...)
}
}

属性

对于 static outlets 数组中定义的每个出口,Stimulus 会向你的控制器添加五个属性,其中 [name] 对应于出口的控制器标识符

类型 属性名称 返回类型 效果
存在性 has[Name]Outlet 布尔值 测试 [name] 出口是否存在
单数 [name]Outlet 控制器 返回第一个 [name] 出口的 Controller 实例,如果不存在则抛出异常
复数 [name]Outlets Array<Controller> 返回所有 [name] 出口的 Controller 实例
单数 [name]OutletElement 元素 返回第一个 [name] 出口的 Controller Element,如果不存在则抛出异常
复数 [name]OutletElements Array<Element> 返回所有 [name] 出口的 Controller Element

注意:对于嵌套的 Stimulus 控制器属性,请务必省略命名空间分隔符,以便正确访问引用的出口

// chat_controller.js

export default class extends Controller {
static outlets = [ "admin--user-status" ]

selectAll(event) {
// returns undefined
this.admin__UserStatusOutlets

// returns controller reference
this.adminUserStatusOutlets
}
}

访问控制器和元素

由于从 [name]Outlet[name]Outlets 属性中获取 Controller 实例,因此还可以访问控制器实例定义的值、类、目标以及所有其他属性和函数

this.userStatusOutlet.idValue
this.userStatusOutlet.imageTarget
this.userStatusOutlet.activeClasses

还可以调用出口控制器可能定义的任何函数

// user_status_controller.js

export default class extends Controller {
markAsSelected(event) {
// ...
}
}

// chat_controller.js

export default class extends Controller {
static outlets = [ "user-status" ]

selectAll(event) {
this.userStatusOutlets.forEach(status => status.markAsSelected(event))
}
}

类似地,使用 Outlet Element 时,它允许在 Element 上调用任何函数或属性

this.userStatusOutletElement.dataset.value
this.userStatusOutletElement.getAttribute("id")
this.userStatusOutletElements.map(status => status.hasAttribute("selected"))

出口回调

出口回调是 Stimulus 调用的特殊命名函数,可让你响应页面中添加或移除出口时的操作。

要观察出口更改,请定义名为 [name]OutletConnected()[name]OutletDisconnected() 的函数。

// chat_controller.js

export default class extends Controller {
static outlets = [ "user-status" ]

userStatusOutletConnected(outlet, element) {
// ...
}

userStatusOutletDisconnected(outlet, element) {
// ...
}
}

假设存在出口

在控制器中访问 Outlet 属性时,断言至少存在一个对应的 Outlet。如果声明缺失且未找到匹配的出口,Stimulus 将抛出异常

Missing outlet element "user-status" for "chat" controller

可选出口

如果 Outlet 是可选的,或者要断言至少存在一个 Outlet,则必须首先使用存在属性检查 Outlet 的存在

if (this.hasUserStatusOutlet) {
this.userStatusOutlet.safelyCallSomethingOnTheOutlet()
}

引用非控制器元素

如果你尝试将没有相应 data-controller 和标识符的元素声明为出口,Stimulus 将抛出异常

<div data-controller="chat" data-chat-user-status-outlet="#user-column"></div>

<div id="user-column"></div>

将导致

Missing "data-controller=user-status" attribute on outlet element for
"chat" controller`

下一步:值