如何显示图像我点击在我的模态?



我是JS的新手,我已经学会了刺激和我使用Rails。我一直试图在我的模态中显示我从我的画廊点击的图像,但它总是显示我的画廊的第一个图像。我不知道如何瞄准我的img的src。这是我的索引页

<div class="container mb-5">
<h1 class='headers'>This is my personal art page</h1>
<div class='image_container' id='app' data-controller="clickable_images">
<% @personals.each do |personal| %>
<div class='img-box'>
<button data-action="click->clickable_images#expandImage"><%= cl_image_tag personal.image.key, class: 'personal_img', data: { target: "image" } %></button>
</div>
<div class="modal" data-controller="slider" data-clickable_images-target="modal">
<div class="modal-dialog">
<div class="modal-content">
<%= cl_image_tag personal.image.key %>
<button data-action="click->slider#close">Close</button>
</div>
</div>
</div>
<% end %>
</div>
</div>`

这是我的两个刺激控制器。模态打开和关闭,我似乎无法瞄准正确的东西。当我打开控制台并按下图像时,它可以工作,它显示我单击不同的图像,但我如何针对动态源以便能够在我的模态中显示单击的图像?

import { Controller } from "stimulus";
export default class extends Controller {
open() {
document.body.classList.add("modal-open");
this.element.setAttribute("style", "display: block;");
this.element.classList.add("show");
document.body.innerHTML += '<div class="modal-backdrop fade show"></div>';
}
close() {
document.body.classList.remove("modal-open");
this.element.removeAttribute("style");
this.element.classList.remove("show");
document.getElementsByClassName("modal-backdrop")[0].remove();
}
}
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["modal"];
expandImage(event) {
let sliderController = this.application.getControllerForElementAndIdentifier(
this.modalTarget,
"slider"
);
sliderController.open();
console.log(event.currentTarget);
}
}

原始方法的问题是你的控制器交叉引用是有bug的。

let sliderController = this.application.getControllerForElementAndIdentifier(
this.modalTarget,
"slider"
);

这里,您有this.modalTarget,但是您的可点击图像控制器在模板循环的范围之外。它会拿起modalTarget,但每次都是第一个。如果你使用this.modalTargets,刺激会给你所有的情态,但你需要一种方法来知道哪个按钮点击了这些目标上的哪个"索引"。


我建议你保持这种方法简单,只有一个控制器(例如viewbox控制器),做你需要在一个类。你可以把它命名为clickable-images,但是这样很长很简单。

我们来修改一下HTML;

  1. 记住可访问性,避免尝试使非按钮的东西可点击,但如果你必须,确保你包括正确的属性。此外,按钮类型应该是'button',否则浏览器会将其视为提交并重新加载页面。也给按钮一个标签。
  2. 将控制器放在包装器上div.img-box
  3. 不需要在预览图像上的目标,因为它没有使用
  4. 使模态成为viewbox控制器的目标
<div class="container mb-5">
<h1 class='headers'>This is my personal art page</h1>
<div class='image_container' id='app'>
<% @personals.each do |personal| %>
<div class='img-box' data-controller="viewbox">
<div class='preview-container'>
<button type="button" data-action="click->viewbox#open">View</button>
<%= cl_image_tag personal.image.key, class: 'personal_img' %>
</div>
<div class="modal" data-viewbox-target="modal">
<div class="modal-dialog">
<div class="modal-content">
<%= cl_image_tag personal.image.key %>
<button data-action="click->viewbox#close">Close</button>
</div>
</div>
</div>
</div>
<% end %>
</div>
</div>

现在,让我们修改模态控制器,它现在几乎完全相同,只是模态内容是一个目标。

import { Controller } from "stimulus";
export default class extends Controller {
static targets = ['modal'];
open() {
const modal = this.modalTarget;
document.body.classList.add("modal-open");
modal.setAttribute("style", "display: block;");
modal.classList.add("show");
document.body.innerHTML += '<div class="modal-backdrop fade show"></div>';
}
close() {
const modal = this.modalTarget;
document.body.classList.remove("modal-open");
modal.removeAttribute("style");
modal.classList.remove("show");
document.getElementsByClassName("modal-backdrop")[0].remove();
}
}

一个小题外话——如果你只使用实际的HTML,而不是Ruby on Rails模板语法,那么人们回答Stimulus问题会容易得多。