简体   繁体   English

干掉一些Rails / HAML / jQuery视图代码

[英]DRYing up some Rails/HAML/jQuery view code

I render an alert bar as a partial at the top of the screen that gets shown to the user for success/failure/notice flash messages. 我在屏幕顶部渲染一个警报栏,显示给用户成功/失败/通知flash消息。

I finally have it working for most scenarios, but the code itself is repetitive for a few parts and I am not sure how I can split it up more efficiently since I am relatively new to all of this. 我终于让它适用于大多数情况,但代码本身对于一些部分是重复的,我不确定如何更有效地分割它,因为我对所有这些都相对较新。 My goal is to try not to repeat myself if possible or at least to minimize how much is repeated. 我的目标是尽可能不重复自己,或者至少尽量减少重复的次数。

For instance, is there a way to place some of the javascript into a re-useable partial or helper function? 例如,有没有办法将一些javascript放入可重用的部分或辅助函数中? Are there other obvious ways of making this code less repetitious? 还有其他明显的方法可以减少重复这些代码吗?

I'm not comfortable enough yet with Rails/Ruby to understand how to improve the code, so any tips you can provide are greatly appreciated! 我对Rails / Ruby感到不舒服,无法理解如何改进代码,因此非常感谢您提供的任何提示!

/ top alert area
#topAlertBar.shadow_medium.soft-hidden

- if flash.empty? && !current_user.confirmed?
  - # User has yet to confirm their account
  - # and there AREN'T any flash messages to show

  #alertBarOffset.colordark.soft-hidden
    / placeholder for alert bar offset

  :javascript
    // Set the flash box content
    $('#topAlertBar').html('Please confirm your account by following the instructions sent to #{current_user.email}.  To resend your confirmation email, #{escape_javascript(link_to("click here", user_resend_confirmation_path(current_user), :class => "inlinelink", :method => :post, :remote => true))} #{escape_javascript(image_tag("ajaxOrange.gif", :class => "soft-hidden mls mbs"))}.');

    // Slides down the top alert bar after page load
    $('#topAlertBar, #alertBarOffset').delay(250).slideDown("fast");

    // Shows & hides AJAX loading GIF when necessary
    $('#topAlertBar a').click(function() {
      $(document).bind('ajaxSend', function(e, request, options) {
        $("#topAlertBar img").show();
      });
      $(document).bind('ajaxComplete', function(e, request, options) {
        $(document).unbind('ajaxSend', 'ajaxComplete');
        $("#topAlertBar img").hide();
      });
    });

- elsif !flash.empty? && !current_user.confirmed?
  - # User has yet to confirm their account
  - # and there ARE flash messages to show

  #alertBarOffset.colordark.soft-hidden
    / placeholder for alert bar offset

  - [:error, :success, :notice].each do |key| 
    - unless flash[key].blank?
      - @msg = flash[key]
      - @key = key

  :javascript
    // Set the flash box content
    var $that = $('#topAlertBar');
    $that.html('#{@msg}').addClass('#{@key}').delay(250).slideDown("fast", function() {
      $(this).delay(2000).slideUp("fast", function () {
        // Remove any CSS modifiers
        $that.removeClass('#{@key}');

        // Set the flash box content
        $('#topAlertBar').html('Please confirm your account by following the instructions sent to #{current_user.email}.  To resend your confirmation email, #{escape_javascript(link_to("click here", user_resend_confirmation_path(current_user), :class => "inlinelink", :method => :post, :remote => true))} #{escape_javascript(image_tag("ajaxOrange.gif", :class => "soft-hidden mls mbs"))}.');

        // Slides down the top alert bar after page load
        $('#topAlertBar, #alertBarOffset').slideDown("fast");

        // Shows & hides AJAX loading GIF when necessary
        $('#topAlertBar a').click(function() {
          $(document).bind('ajaxSend', function(e, request, options) {
            $("#topAlertBar img").show();
          });
          $(document).bind('ajaxComplete', function(e, request, options) {
            $(document).unbind('ajaxSend', 'ajaxComplete');
            $("#topAlertBar img").hide();
          });
        });

      });
    });


- elsif !flash.empty?
  - # User is confirmed
  - # and there ARE flash messages to show

  - [:error, :success, :notice].each do |key| 
    - unless flash[key].blank?
      - @msg = flash[key]
      - @key = key

  :javascript
    // Set the flash box content
    var $that = $('#topAlertBar');
    $that.html('#{@msg}').addClass('#{@key}').delay(250).slideDown("fast", function() {
      $(this).delay(2000).slideUp("fast");
    });

Why bother with all the different states of user confirmation? 为什么要打扰用户确认的所有不同状态? Just have your application_controller set a flash alert if the user isn't confirmed. 如果用户未得到确认,请让您的application_controller设置闪光警报。

Secondly -- move all the jquery to application.js and run it on every page -- it should slide your content down if it exists, otherwise do nothing. 其次 - 将所有jquery移动到application.js并在每个页面上运行它 - 它应该将内容向下滑动(如果存在),否则什么都不做。

Finally, grab a flash helper like the following: http://snippets.dzone.com/posts/show/6440 and then call it in your layout like 最后,抓住一个flash帮助器,如下所示: http//snippets.dzone.com/posts/show/6440然后在你的布局中调用它

%head
  %titile
  =javascript_include_tag :all
  =yield(:header)
%body
  =display_flash
  =yield

I ended up taking a different approach than what Jesse recommended, but he still helped get me thinking about ways to refactor the code. 我最终采取了与Jesse推荐的方法不同的方法,但他仍然帮助我思考如何重构代码。 Here is the end result which is as DRY as I could get it without completely changing how I already had it implemented. 这是最终的结果,就像我可以得到它而没有完全改变我已经实现它的方式。

Hopefully this will help someone else who stumbles upon this question in the future. 希望这将有助于将来偶然发现这个问题的其他人。


In my ApplicationHelper (this is modified somewhat from the original question so it now works for my validation errors as well as regular flash messages) 在我的ApplicationHelper中 (这与原始问题稍有不同,所以它现在适用于我的验证错误以及常规flash消息)

  def display_flash_messages
    if !flash.empty?
      [:error, :success, :notice, :warning].each do |key| 
        unless flash[key].blank?
          @flash_key = key
          if flash[key].kind_of?(Array) && flash[key].size > 1
            @flash_msg = flash[key].join(' & ')
          elsif flash[key].kind_of?(Array) && flash[key].size == 1
            @flash_msg = flash[key].first
          elsif flash[key].kind_of?(String)
            @flash_msg = flash[key]
          end
        end
      end
    end
    return
  end

In my main layout file, I'm just doing: 在我的主要布局文件中,我只是在做:

  %body
    - if signed_in?
      = render 'shared/top_alert_bar'

In the top alert bar file 在顶部警报栏文件中

= display_flash_messages

/ top alert area
#topAlertBar.shadow_medium.soft-hidden
- if !current_user.confirmed?
  #alertBarOffset.colordark.soft-hidden
    / placeholder for alert bar offset

- if flash.empty? && !current_user.confirmed?
  - # User has yet to confirm their account
  - # and there AREN'T any flash messages to show

  :javascript
    #{render('shared/js/confirm_user')}

- elsif !flash.empty?

  :javascript
    // Set the flash box content
    var $that = $('#topAlertBar');
    $that.html('#{@flash_msg}').addClass('#{@flash_key}').delay(250).slideDown("fast", function() {
      $(this).delay(4000).slideUp("fast", function () {
        // Remove any CSS modifiers
        $that.removeClass('#{@flash_key}');

        #{!current_user.confirmed? ? render('shared/js/confirm_user') : ""}

      });
    });

In the confirm_user partial 在confirm_user部分中

:plain
  $('#topAlertBar').html('Please confirm your account by following the instructions sent to #{current_user.email}.  To resend your confirmation email, #{escape_javascript(link_to('click here', user_resend_confirmation_path(current_user), :class => 'inlinelink', :method => :post, :remote => true))}. #{escape_javascript(image_tag('ajaxOrange.gif', :class => 'soft-hidden mls mbs'))}');

  $('#topAlertBar, #alertBarOffset').delay(250).slideDown('fast');

And finally, I moved this to my main js file 最后,我把它移到我的主js文件中

/* ******************************** */
/* Top Alert Bar for Flash Messages */
/* ******************************** */
// Description: Shows & hides AJAX loading GIF when necessary
$('#topAlertBar a').click(function() {
  $(document).bind('ajaxSend', function(e, request, options) {
    $("#topAlertBar img").show();
  });
  $(document).bind('ajaxComplete', function(e, request, options) {
    $("#topAlertBar img").hide();
    $(document).unbind('ajaxSend', 'ajaxComplete');
  });

}); });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM