javascript / частичная логика для файлового менеджера
-
13-12-2019 - |
Вопрос
По сути, я пытаюсь создать файловый менеджер для своего приложения rails, аналогичный тому, как функционирует раздел "Медиа" WordPress.В настоящее время у меня есть модель под названием Asset
именно сюда заходят пользователи, чтобы загрузить различные изображения.В различных других моделях у меня есть поле для изображений, которое является просто текстовым полем.Я надеюсь, что когда пользователь нажмет на текстовое поле, он откроет "менеджер активов" в модальном окне со всеми содержащимися внутри изображениями Asset
показ.Когда пользователь нажимает на одно из изображений, он должен закрыть модальный режим и заполнить текстовое поле URL-адресом выбранного изображения.
У меня есть модель под названием Events
который содержит текстовое поле, о котором я говорил.В new
действие, на которое я отвечаю в js, в котором я загружаю фрагмент, содержащий все ресурсы в модальном окне, как я и ожидал.Моя единственная проблема в том, что я делаю это с помощью $.getScript
вызов, и я не могу вызвать какой-либо дополнительный javascript для загрузки URL-адреса изображения обратно в текстовое поле, я предполагаю, что это потому, что объекты еще не существуют.В любом случае, перейдем к коду:
контроллер
def new
@event = Event.new
@asset = Asset.all
end
respond_to do |f|
f.html
f.js
end
new.js
$('.acontainer').html('<%= render @asset %>');
page.js
//when a user clicks the image field, show the asset partial
$('.image-field').click(function() {
$.getScript('edit.js');
});
// when a user clicks an image, add it's src to the image field <-- does nothing
$('.actonainer img').click(function() {
$('.image-field').val($(this).attr('src'));
});
Я был бы очень признателен за любые идеи, особенно если кто-нибудь знает лучший способ сделать это.:-)
Решение
Похоже, вы, возможно, привязываете событие click к элементам .acontainer img DOM, которые в данный момент не существуют, поскольку вы извлекаете их при нажатии .image-field.
В общем, вы должны использовать jQuery.на и привяжите ваши события к корню документа.Это называется делегированием.Когда вы нажимаете на ссылку, событие всплывает и попадает в узел документа, и он обрабатывает событие.Таким образом, когда вы добавляете элементы DOM через ajax или непосредственно в DOM, они все равно получат обработчик события, который вы намеревались.
$(function() {
$(document).on('click', '.acontainer img', function(event) {
$('.image-field').val($(this).attr('src'));
})
});
Однако здесь есть более серьезная проблема.Похоже, у вас есть несколько элементов .image-field на странице.Что вам, возможно, потребуется сделать в вашем обработчике .image-field, так это вернуть HTML, а не js, чтобы вы могли привязать событие к корневому элементу недавно добавленного HTML.Этот блок будет идентифицировать конкретное поле ввода, значение которого он может установить при щелчке по изображению.
$(function() {
$(document).on('click', '.image-field',
function(event) {
var field = $(this);
$.ajax('/edit', {
success: function(data, textStatus, jqXHR) {
var blah = $(Dialog.new(data));
// Create a modal and return its root DOM element
blah.on('click', 'img',
function(event) {
field.val($(this).attr('src'));
});
}
})
});
});
Последнее замечание: возможно, вы захотите рассмотреть возможность использования контроллера RESTful для ваших ресурсов.Возможно, вы не захотите извлекать один ресурс (Asset) из контроллера с именем EventsController, особенно с помощью действия редактирования.Вы хотите, чтобы GET AssetsController::index возвращал список активов.
Другие советы
Ничего не происходит, когда вы нажимаете на изображения, потому что первоначальный запрос для ".acontainer img"
не возвращает никаких элементов, и поэтому обработчик события ни к чему не привязан.Они еще не были загружены.
Возможно, вы захотите попробовать jQuery - это live
метод.Он прикрепляет обработчики к элементам, присутствующим при загрузке страницы и элементы, позже добавленные в DOM.
Обновление: Как указывает @aceofspades, live
является устаревшим в jQuery 1.7.Воспользуйся on
вместо.