【问题标题】:javascript / partial logic for a file manager文件管理器的 javascript / 部分逻辑
【发布时间】:2012-03-14 02:29:16
【问题描述】:

我基本上是在尝试为我的 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'));
});

任何想法都将不胜感激,特别是如果有人知道更好的方法来做到这一点。 :-)

【问题讨论】:

    标签: javascript ruby-on-rails partials file-manager


    【解决方案1】:

    看起来您可能正在将点击事件绑定到当时不存在的 .acontainer img DOM 元素,因为您在点击 .image-field 时会检索它们。

    一般来说,您应该使用jQuery.on 并将您的事件绑定到文档根目录。这称为委托。当你点击一个链接时,事件会冒泡并点击文档节点,它会处理这个事件。这样,当您通过 ajax 或直接在 DOM 中添加 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 返回资产列表。

    【讨论】:

      【解决方案2】:

      单击图像时什么都没有发生,因为".acontainer img" 的初始查询没有返回任何元素,因此事件处理程序没有附加到任何东西。它们尚未加载。

      您可能想试试jQuery's live method。它将处理程序附加到页面加载时出现的元素稍后添加到 DOM 的元素。


      更新:正如@aceofspades 指出的那样,live 在 jQuery 1.7 中已被弃用。请改用on

      【讨论】:

      • 赞成您的回答也是正确的 - 感谢您的帮助。
      • 我刚刚发现jQuery的live()和delegate()已经被on()替换了,我相信v1.7。
      猜你喜欢
      • 1970-01-01
      • 2012-01-26
      • 1970-01-01
      • 2011-04-19
      • 2017-02-07
      • 2021-01-02
      • 1970-01-01
      • 2012-01-02
      • 1970-01-01
      相关资源
      最近更新 更多