Rails Ruby China 发帖的这种编辑预览是怎么实现?

chengkai1853 · 2015年09月14日 · 最后由 chengkai1853 回复于 2015年09月15日 · 2356 次阅读

我把 ruby-china 的代码下载下来了,想看看 markdown 预览效果是怎么实现的。看了下源代码如下 pages/_form.html.erb:

<%= simple_form_for @page do |f| %>
  <%= render "shared/error_messages", target: @page %>

  <%= f.input :slug, hint: "http://#{Setting.domain}/wiki/:slug"%>
  <%= f.input :title, input_html: { class: "xxlarge" } %>

  <div class="form-group">
    <div class="editor-toolbar col-sm-offset-2 col-sm-10">
      <ul class="nav nav-pills">
        <li class="edit active"><%= link_to(t("common.editor_toolbar_edit"), "#") %></li>
        <li class="preview"><%= link_to(t("common.editor_toolbar_preview"), "#") %></li>
      </ul>
    </div>
  </div>

  <%= f.input :body, as: :text, input_html: { rows: "30" },
        hint: "请使用 Markdown 格式编写,可以试试用 <a href='http://mouapp.com' target='_blank'>Mou</a> 这个 App 来编写。".html_safe %>
  <% if not @page.new_record? %>
    <%= f.input :change_desc, as: :text, input_html: { rows: "2" }, hint: t("pages.describe_this_time_change") %>
  <% end %>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
      <%= f.submit t("common.save"), class: "btn btn-primary", 'data-disable-with' => t("common.saving") %>
      <%= link_to t("common.cancel"), pages_path, class: "btn btn-default reset" %>
    </div>
  </div>
<% end %>

而 pages.coffee 相应的 coffee 的代码是这样的:

window.PageView = Backbone.View.extend
  el: "body"
  events:
    "click .editor-toolbar .edit a": "toggleEditView"
    "click .editor-toolbar .preview a": "togglePreviewView"

  initialize: (opts) ->
    @parentView = opts.parentView
    $("<div id='preview' class='markdown form-control'></div>").insertAfter( $('#page_body') )

  toggleEditView: (e) ->
    $(e.target).parent().addClass('active')
    $('.preview a').parent().removeClass('active')
    $('#preview').hide()
    $('#page_body').show()
    false

  togglePreviewView: (e) ->
    $(e.target).parent().addClass('active')
    $('.edit a').parent().removeClass('active')
    $('#preview').html('Loading...')
    $('#page_body').hide()
    $('#preview').show()
    $.post '/wiki/preview', {body: $('#page_body').val()}, (data)->
      $('#preview').html(data)
      false
    false

问题是

<li class="edit active"><%= link_to(t("common.editor_toolbar_edit"), "#") %></li>
<li class="preview"><%= link_to(t("common.editor_toolbar_preview"), "#") %></li>

这个都是连接到‘#'本页,它是怎么实现逻辑的啊?参数传递什么的,都是怎么样实现的呢?那个 js 的

el: "body"
  events:
    "click .editor-toolbar .edit a": "toggleEditView"
    "click .editor-toolbar .preview a": "togglePreviewView"

是什么意思啊?具体实现逻辑是怎么样的呢?求分解下这个 js 代码。如果有更简单的方法显示,也求方法。先谢谢了啊。

$.post '/wiki/preview', {body: $('#page_body').val()}, (data)->
  $('#preview').html(data)
  false
``

链接地址 # 是用来忽略的。

就是把页面上用户输入的文本内容,通过 ajax 请求发送到服务器,服务器上通过 markdownconverter 这种东东,记得是 redcarpet 这个 gem,转化成 html,然后 preview 节点显示出转化后的 html。

ruby-china 实现的这个 markdown 编辑效果,可以抽离出来到自己的博客系统或其它地方什么的

#2 楼 @rei 谢谢,刚刚 google 中,发现是我 jquery 只看了基础的知识的原因,所以看不懂,要恶补 jquery 去了

#2 楼 @rei 请问一下,里面的page_body是什么啊?而且在 post 的时候会用{body: $('#page_body').val()}这个值。关键是页面上好像都没有 ( $('#page_body') ) 这个 id 的元素。另外附上它出现的地方

app/assets/javascripts/pages.coffee
13:    $("<div id='preview' class='markdown form-control'></div>").insertAfter( $('#page_body') )
19:    $('#page_body').show()
26:    $('#page_body').hide()
28:    $.post '/wiki/preview', {body: $('#page_body').val()}, (data)->
需要 登录 后方可回复, 如果你还没有账号请 注册新账号