JavaScript / частичная логика для файлового менеджера - PullRequest
0 голосов
/ 14 марта 2012

Я в основном пытаюсь создать файловый менеджер для моего приложения 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'));
});

Любые идеи будут высоко цениться, особенно если кто-нибудь знает лучший способ сделать это. : -)

Ответы [ 2 ]

2 голосов
/ 14 марта 2012

Похоже, вы связываете событие click с DOM-элементами .acontainer img, которых в данный момент не существует, поскольку вы извлекаете их, когда нажимаете .image-field.

Как правило, вы должны использовать jQuery.on и привязывать свои события к корню документа. Это называется делегированием. Когда вы нажимаете на ссылку, событие всплывает и попадает на узел документа, и оно обрабатывает событие. Таким образом, когда вы добавляете элементы 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 для ваших активов. Возможно, вы не захотите получать один ресурс (актив) из контроллера с именем EventsController, особенно с помощью действия редактирования. Вы хотите, чтобы GET AssetsController :: index возвращал список активов.

1 голос
/ 14 марта 2012

Ничего не происходит, когда вы щелкаете по изображениям, потому что начальный запрос для ".acontainer img" не возвращает никаких элементов, и поэтому обработчик событий не прикрепляется ни к чему. Они еще не загружены.

Вы можете попробовать метод jQuery live . Он прикрепляет обработчики к элементам, присутствующим при загрузке страницы и элементов, позже добавленных в DOM.


Обновление: Как указывает @aceofspades, live устарела в jQuery 1.7. Вместо этого используйте on.

...