带有涡轮框架的轨道主动连杆样式

问题描述 投票:0回答:4

我有这样的链接:

- @glossaries.each do |g|
  %a.{ :href => glossary_path(g), data: { 'turbo_frame': :'entry' } }
    = g.title

如果单击

g.title
链接的结果在另一个框架中呈现,如何设置活动链接(活动词汇表)的样式?

如果当前路径等于请求的路径,我尝试使用帮助器提供某个类的链接,但它不起作用。没有为链接提供“活动”类别:

def current_class?(test_path)
    return 'active' if request.path == test_path
    ''
  end

使用框架时,当前路径未显示在浏览器地址栏中,因此我尝试通过

data-turbo-action" => "advance"
强制它。使用该浏览器,地址栏中有当前路径,但链接仍然没有“活动”类..

ruby-on-rails link-to stimulusjs hotwire-rails turbo
4个回答
3
投票

我编写这个刺激控制器来处理

turbo:click
事件并使单击的元素处于活动状态。当另一个
turbo:click
事件处理程序取消访问时会出现问题,但在这个地方我不关心它。

import { Controller } from "@hotwired/stimulus";

export default class extends Controller{
  static targets = ['link']
  static classes = ['active']

  initialize(){
    this.handleTurboClick = this.handleTurboClick.bind(this)
  }

  connect(){
    this.element.addEventListener('turbo:click', this.handleTurboClick)
  }

  disconnect(){
    this.element.removeEventListener('turbo:click', this.handleTurboClick)
  }

  handleTurboClick(event){
    this.linkTargets.forEach(target => {
      if(target == event.target){
        target.classList.add(...this._activeClasses)
      }else{
        target.classList.remove(...this._activeClasses)
      }
    })
  }

  get _activeClasses(){
    return this.activeClasses.length == 0 ? ['active'] : this.activeClasses
  }
}
<div data-controller="turbo-active-link" data-turbo-active-link-active-class="bg-gray-300 hover:bg-gray-300" data-turbo-frame="main">
  <a href="/a" data-turbo-active-link-target="link">link A</a>
  <a href="/b" data-turbo-active-link-target="link">link B</a>
</div

1
投票

它不会更新的原因是因为另一个框架正在导航,而页面的其余部分保持不变。要使其显示活动导航链接,您需要重新加载两者或使用一些自定义 JavaScript。我宁愿重新加载两侧,我会在导航和侧面板周围做另一个涡轮框架,就像这样

<%= turbo_frame_tag "glosarries_index" do %>
  ... Navigation links would be here but remove the data-turbo-frame it will automatically use the closest parent.
  <%= turbo_frame_tag "entry" do %>
    ...
  <% end %>
<% end %>

1
投票

我发现上面的答案有效,但过于复杂,所以我构建了一个更简单的解决方案,需要更少的样板。该解决方案还更好地遵循刺激约定,因为它不使用自定义事件处理程序而仅使用目标

刺激控制器:

import { Controller } from "stimulus";

export default class extends Controller {
  static classes = ['active']

  connect() {
    this.active_link = null;
  }

  disconnect() {
    this.active_link = null;
  }

  handleTurboClick(event) {
    if (this.active_link) {
      this.active_link.classList.remove(this.activeClass);
    }
    this.active_link = event.target.closest('a');
    this.active_link.classList.add(this.activeClass);
  }
}

html:

<div data-controller="turbo-active-link" data-turbo-active-link-active-class="bg-gray-300 hover:bg-gray-300">
  <a href="/a" action="turbo:click->turbo-active-link#handleTurboClick" data-turbo-frame="main">link A</a>
  <a href="/b" action="turbo:click->turbo-active-link#handleTurboClick" data-turbo-frame="main">link B</a>
</div

0
投票

我将发布另一种方法。这就是我现在设计选项卡的方式。

active_tab_controller.js:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["link"]

  connect() {
    this.linkTargets[0].classList.add("active");
    this.linkTargets[1].classList.add("shadow-inner");
  }

  setActive(event) {
    this.linkTargets.forEach(link => {
      link.classList.remove("active")
      link.classList.add("shadow-inner")
    })

    event.currentTarget.classList.add("active")
    event.currentTarget.classList.remove("shadow-inner ")
  }
}

application.tailwind.css:

.active { @apply
  border border-b-0 border-gray-300 bg-gradient-to-b from-neutral-50 to-neutral-100
}

html:

.flex{ data: { controller: "active-tab" } }
  = link_to main_tab_user_project_path(@user, @project), data: {turbo_frame: "tab_content", action: "click->active-tab#setActive", "active-tab-target" => "link"} do
    = image_tag "list.svg"
    .px-1 to-dos
  = link_to second_tab_user_project_path(@user, @project), data: {turbo_frame: "tab_content", action: "click->active-tab#setActive", "active-tab-target" => "link"} do
    = image_tag "link.svg"
    .px-1 links

= turbo_frame_tag "tab_content" do
  = render "main_tab"
© www.soinside.com 2019 - 2024. All rights reserved.