刺激嵌套(子)目标



是否可以(以及是否合适(使用父目标的嵌套/子目标?

例如,我有"N+"菜单项,每个项(包装器(都包含链接和列表。我可以将data-main-menu-target="menuItem"添加到每个父项,然后使用this.menuItemTargets.forEach(...)在控制器循环中对它们进行迭代

但是,在每次循环迭代中为每个菜单项目标找到菜单项链接和菜单项列表的最佳实践是什么?

通常,我也可以为那些元素添加目标,例如menuItemLink&menuItemList,但我如何从父menuItem目标中选择它们,有可能做类似menuItemTarget.find(this.this.menuListTarget)的事情吗?

可视化结构如下:

data-controller="main-menu"
data-main-menu-target="menuItem"
data-main-menu-target="menuLink"
data-main-menu-target="menuList"
....
data-main-menu-target="menuItem"
data-main-menu-target="menuLink"
data-main-menu-target="menuList"
....

然后如何选择";CCD_ 7";对于某些";CCD_ 8";每个循环的目标?

您可以构造控制器,使其具有一个menu控制器,该控制器可用于根菜单和其中的子菜单。这可以从任何被认为是根的地方递归访问。

示例代码

  • 在下面的HTML中,我们有一个导航,其中包含菜单的ul,每个子项都应该是item目标
  • 在每个item内,我们可以具有link目标或另一个子菜单,该子菜单本身是另一个menu控制器,并且模式继续
<nav>
<ul class="menu-list" data-controller="menu" data-menu-target="root">
<li data-menu-target="item">
<a data-menu-target="link">Team Settings</a>
</li>
<li data-menu-target="item">
<ul data-controller="menu">
<li data-menu-target="item">
<a data-menu-target="link">Members</a>
</li>
<li data-menu-target="item">
<a data-menu-target="link">Plugins</a>
</li>
<li data-menu-target="item">
<a data-menu-target="link">Add a member</a>
</li>
</ul>
</li>
<li data-menu-target="item">
<a data-menu-target="link">Invitations</a>
</li>
<li data-menu-target="item">
<a data-menu-target="link">Cloud Storage Environment Settings</a>
</li>
</ul>
</nav>
  • 在我们的控制器中,我们首先通过检查this.hasRootTarget来确定这个控制器的实例是否是根
  • 控制器只能访问其"作用域"元素,因此根只能"查看"嵌套data-controller='menu'之外的子级
  • 我们需要使用setTimeout来等待任何子控制器连接,可能有更好的事件传播方式可以做到这一点
  • 可以通过getControllerForElementAndIdentifier方法访问元素上的控制器
  • 从这里,我们可以将菜单结构确定为link目标的数组或本身将包含子link目标的嵌套数组
  • 我们可以使用Node.contains方法来映射每个item,并查看其中"包含"了哪些链接
  • 这种方法可以进行改进,以获得您需要使用的结构
class MenuController extends Controller {
static targets = ['item', 'link', 'root'];
connect() {
if (this.hasRootTarget) {
setTimeout(() => {
// must use setTimeout to ensure any sub-menus are connected
// alternative approach would be to fire a 'ready' like event on submenus
console.log('main menu', this.getMenuStructure());
});
}
}
getMenuStructure() {
const links = this.linkTargets;
return this.itemTargets.map((item) => {
const child = item.firstElementChild;
const subMenu = this.application.getControllerForElementAndIdentifier(
child,
this.identifier
);
const menuLinks = links.filter((link) => item.contains(link));
return subMenu ? subMenu.getMenuStructure() : menuLinks;
});
}
}

备注

  • 我们通过firstElementChild访问DOM,这可能不是我们在Stimulus中想要的方式,但您可以简单地添加另一种目标类型的"子菜单",使其更加明确,并遵循在每个项目中以这种方式找到"链接"的模式
  • 提醒您不能将data-controller="menu"放在data-menu-target="item"上,因为这将从父作用域中删除item。根据范围文档

该元素及其所有子元素构成了控制器的作用域。

来自另一个对话的回答,

A(对于menuLink和menuList,您可以自己处理:使用CSS类,然后使用普通选择器。因此,一旦您使用menuItem目标以找到您想要的menuItem,然后执行menuItem.querySelector('.menu-link'(。不是刺激方案,但它非常简单,能够";后退";然后做如果需要的话,手动操作。

B( 我不确定你的整体刺激控制器要做什么,但有可能应该有一个菜单项控制器存在于menuItem目标上。取决于你想要做什么完成,可以取代主菜单控制器,或者很可能(因为我假设你在顶部做一些"工作"级别主菜单,在那里你想知道所有的";项目"(,在里面除了主菜单控制器之外。通过此设置,您的主菜单控制器可以在menuItem目标上循环,直接使用其底层控制器实例,甚至调用方法这不是我在教程中展示的东西,但它不是不同寻常的模式:你会暴露";控制器实例";的"菜单项";控制器的元件-例如。https://www.betterstimulus....(这个例子的最大区别是两个控制器都在同一个元件上,所以调整相应地(。

(c(编织

最新更新