ror突进-js的评价rating

评价系统其实是个input单选框,换成了星星样式而已,基本上是个纯前端的效果,使用现成的jquery基础上的plugin就可以了,实测可用的项目地址如下
https://github.com/wbotelhos/raty/

其中有用的只有

https://github.com/wbotelhos/raty/blob/master/lib/jquery.raty.js
https://github.com/wbotelhos/raty/blob/master/lib/jquery.raty.css

这两个文件,把这两个文件分别放在项目的

app/assets/javascripts
app/assets/stylesheets

下面

然后需要设置一下页面的预备载入,初始化时候加入该文件位置

config/initializers/assets.rb
Rails.application.config.assets.precompile += %w( jquery.raty.css )
Rails.application.config.assets.precompile += %w( jquery.raty.js )

但是这里面还是有个问题需要解决,就是需要设置评分的星星样式
比如我设置了两个图片分别是

star-off.png
start-on.png

图片下载地址如下

https://ooo.0o0.ooo/2016/11/21/5832a40577f56.png
https://ooo.0o0.ooo/2016/11/21/5832a40578015.png

直接放在了 public/ 下面,这样我就能通过/star-off.png和/star-on.png来直接调用

都设置完成后,我终于可以再项目中使用了
首先我需要做个带id的div

<div id="rating-for-message-1" class="text-center"></div>

在我需要给该rating嵌入一个script

          $("#rating-for-message-1").raty({
            path:"/",
            starOff: 'star-off.png',
            starOn: 'star-on.png',
            size: 32
          });

这就行了,跑起来后浏览器会把它渲染成为一个input,到时候里面填好值,直接放到表单里submit提交就行了

Ajax提交rating

如果是简单的表单提交评价,以上即可,如果是ajax提交要求页面不刷新,需要继续往下看

ajax提交首先后台需要有个接收提交的controller的action,比如这个接收三个参数conversation_id,message_id,rating

  # 评价系统

  def rating
    # 获取message的参数

    conversation_id = params[:conversation_id]
    message_id = params[:message_id]
    score = params[:rating]

    # 找到指定的message

    conversation = Conversation.find(conversation_id.to_i)
    message = conversation.messages.find(message_id.to_i)
    # 为message评级

    message.rating = score
    message.save

    return 'success'
  end

然后路由需要把它放出来

  # 评价系统

  collection do
    post :rating
  end

然后js部分比较繁琐

    $(function() {

        // 初始化rating选框

        function initRating(obj) {
          obj.raty({
            path:"/",
            starOff: 'star-off.png',
            starOn: 'star-on.png',
            size: 32,
            click: function(score, evt) {
              // ajax提交

              ajaxRating(score);
              // 锁定rating

              lockRating(obj,score)
            }
          });
        };

        // ajax提交评级

        function ajaxRating(score) {
          $.ajax({
            url: '<%= rating_account_questions_path %>',
            type: 'POST',
            dataType: 'json',
            data: {
              'conversation_id' : <%= @conversation.id %>,
              'message_id' : <%= m.id %>,
              'rating': score
            },
          })
          .done(function() {
            console.log("raty success");
          })
          .fail(function() {
            console.log("raty error");
          })
          .always(function() {
            console.log("raty complete");
          });
        };

        // 锁定星星不可重新提交

        function lockRating(obj,score) {
          // 锁定部分样式

          obj.raty({
            path:"/",
            starOff: 'star-off.png',
            starOn: 'star-on.png',
            size: 32,
            readOnly: true, score: score
          });
        };

        // 允许评分的对象

        var ratableObj = $('#rating-for-message-<%= m.id %>');
        initRating(ratableObj);
        // 已经评过分的对象

        var unRatableObj = $('#raty-for-message-<%= m.id %>');
        lockRating(unRatableObj,'<%= m.rating %>');


      });
      </script>

细节是:
首先需要有个初始页面自动加载的函数

$(function() {
  // 需要运行的所有js

});

然后需要区分两种星星,一种评价前的一种评价后的,使用不同的js函数来处理

        // 允许评分的对象

        var ratableObj = $('#rating-for-message-<%= m.id %>');
        initRating(ratableObj);
        // 已经评过分的对象

        var unRatableObj = $('#raty-for-message-<%= m.id %>');
        lockRating(unRatableObj,'<%= m.rating %>');

分别写initRating()和lockRating()
initRating()

        // 初始化rating选框

        function initRating(obj) {
          obj.raty({
            path:"/",
            starOff: 'star-off.png',
            starOn: 'star-on.png',
            size: 32,
            click: function(score, evt) {
              // ajax提交

              // 锁定rating

            }
          });
        };

lockRating()

        // 锁定星星不可重新提交

        function lockRating(obj,score) {
          // 锁定部分样式

          obj.raty({
            path:"/",
            starOff: 'star-off.png',
            starOn: 'star-on.png',
            size: 32,
            readOnly: true, score: score
          });
        };

未评价的input点击后事件是

           click: function(score, evt) {
              // ajax提交

              ajaxRating(score);
              // 锁定rating

              lockRating(obj,score)
            }

由于『锁定rating』直接用lockRating()就可以了,而『ajax提交』需要另外写,用来提交这三个参数
ajaxRating()

        // ajax提交评级

        function ajaxRating(score) {
          $.ajax({
            url: '<%= rating_account_questions_path %>',
            type: 'POST',
            dataType: 'json',
            data: {
              'conversation_id' : <%= @conversation.id %>,
              'message_id' : <%= m.id %>,
              'rating': score
            },
          })
          .done(function() {
            console.log("raty success");
          })
          .fail(function() {
            console.log("raty error");
          })
          .always(function() {
            console.log("raty complete");
          });
        };