javascript功能不可见?没有第二次被召唤

时间:2015-01-24 11:32:47

标签: javascript ruby-on-rails-4 backbone.js raphael

这可能是一个非常新手的问题所以请耐心等待。我正在修补Ruby on Rails 4,Javascript和Raphael。我也使用Backbone。在我的根页面上,我有两个按钮,一个用Raphael渲染一些东西,另一个在更改相关参数后应该做同样的事情。

在我的application.js中,我得到了以下内容:

var app = {};
$(document).ready(function() {
  app.paper = Raphael("canvas", 1000,700); // canvas: html div
  ...
  app.Room = Backbone.Model.extend({
    ...
  }
  app.RoomList = Backbone.Collection.extend({
    model: app.Room
  });
  ...
  app.drawRoom = function(room, x, y, z) {
    ...
  }
  ...
});

点击第一个按钮后,.js.erb视图会启动并调用以下内容:

// retrieve data, stuff it into app.roomList, then this:
app.drawRoom(app.roomList.first(), 500, 300, 0);

这可以按预期工作,并呈现一些圈子和东西。还有一些东西会在幕后发生(房间数据是通过RabbitMQ从不同项目的CDO服务器中检索出的json,但它完全不相关)。现在,当我点击第二个按钮时,我正在执行以下操作:

app.paper.clear();
app.drawRoom(app.roomList.first(), 800, 300, 1);

正如您所看到的,我的目的是清理画布并使用不同的参数重绘所有内容。新参数没问题,我按下第二个按钮时检查了以下情况,有效地将画布保持干净,除了一个孤独的圆圈:

app.paper.clear();
app.paper.circle(222, 333, 15);

所以我很确定它必须与我对javascript的无知有关。我也很肯定第二次调用app.drawRoom()没有被执行,我用Firebug测试了它。也许一些可见性问题?提前致谢!!编辑:按钮的HTML:

= form_tag( show_rooms_url, remote: true) do
  = submit_tag "show rooms"
= form_tag( up_level_url, remote: true) do
  = submit_tag "+1"

其中routes.rb与两个独立的控制器方法相关联:

def show_rooms
    conn = Bunny.new(:automatically_recover => false)
    conn.start

    ch = conn.create_channel

    client   = ApplicationHelper::RPCClient.new(ch, "rpc_queue")
    response = client.call("list_rooms")
    ch.close
    conn.close
    respond_to do |format|
        format.js { render partial: "show_rooms", locals: { response: response } }
    end
end

def up_level
    respond_to do |format|
        format.js { render partial: "up_level" }
    end
end

然后视图结合以下调用(实际上,只是不同的参数):

app.drawRoom(app.roomList.first(), 500, 300, 0);

为按钮生成的HTML是:

<form method="post" data-remote="true" accept-charset="UTF-8" action="http://localhost:3000/show_rooms">
  <input type="hidden" value="✓" name="utf8">
  <input type="submit" value="show rooms" name="commit">

<form method="post" data-remote="true" accept-charset="UTF-8" action="http://localhost:3000/up_level">
  <input type="hidden" value="✓" name="utf8">
  <input type="submit" value="+1" name="commit">

另外,drawRoom方法:

$(document).ready(function(){
....
app.drawRoom = function(room, x, y, z) {
    if (room.get('drawn') == false) {
        room.set('drawn', true);
        if (app.level === z) {
            c = app.paper.circle(x, y, 15);
            c.attr("fill", "red");
        }

        if (room.get('n') !== "") {
            if (app.level === z) {
                app.paper.path(['M', x - 10, y - 10, 'Q', x - 20, y - 25, x - 10, y - 40]);
            }
            app.drawRoom(app.roomList.where({ id: room.get('n') })[0], x, y - 50, z);
        }
        if (room.get('e') !== "") {
            if (app.level === z) {
                app.paper.path(['M', x + 10, y - 10, 'Q', x + 25, y - 20, x + 40, y - 10]);
            }
            app.drawRoom(app.roomList.where({ id: room.get('e') })[0], x + 50, y, z);
        }
        if (room.get('s') !== "") {
            if (app.level === z) {
                app.paper.path(['M', x + 10, y + 10, 'Q', x + 20, y + 25, x + 10, y + 40]);
            }
            app.drawRoom(app.roomList.where({ id: room.get('s') })[0], x, y + 50, z);
        }
        if (room.get('w') !== "") {
            if (app.level === z) {
                app.paper.path(['M', x - 10, y + 10, 'Q', x - 25, y + 20, x - 40, y + 10]);
            }
            app.drawRoom(app.roomList.where({ id: room.get('w') })[0], x - 50, y, z);

        }
        if (room.get('u') !== "") {
            app.drawRoom(app.roomList.where({ id: room.get('u') })[0], x, y, z + 1);
        }
        if (room.get('d') !== "") {
            app.drawRoom(app.roomList.where({ id: room.get('d') })[0], x, y, z - 1);
        }
    }
}
});

1 个答案:

答案 0 :(得分:2)

您第二次尝试绘制任何内容都失败了,因为Backbone模型上的drawn变量已设置为true。如果该特定属性为true,则以下代码指定要绘制的

if (room.get('drawn') == false) {
    room.set('drawn', true);

    // your room drawing code is here

}

如果您想保留布尔绘制的标志,请将if语句全部放在方法的开头,如下所示:

if (room.get('drawn') == false) {
    room.set('drawn', true);
}

// your room drawing code should be here

要明确的是,整个drawRoom方法应该如下所示:

app.drawRoom = function(room, x, y, z) {
    if (room.get('drawn') == false) {
        room.set('drawn', true);
    }
    if (app.level === z) {
        c = app.paper.circle(x, y, 15);
        c.attr("fill", "red");
    }
    if (room.get('n') !== "") {
        if (app.level === z) {
            app.paper.path(['M', x - 10, y - 10, 'Q', x - 20, y - 25, x - 10, y - 40]);
        }
        app.drawRoom(app.roomList.where({ id: room.get('n') })[0], x, y - 50, z);
    }
    if (room.get('e') !== "") {
        if (app.level === z) {
            app.paper.path(['M', x + 10, y - 10, 'Q', x + 25, y - 20, x + 40, y - 10]);
        }
        app.drawRoom(app.roomList.where({ id: room.get('e') })[0], x + 50, y, z);
    }
    if (room.get('s') !== "") {
        if (app.level === z) {
            app.paper.path(['M', x + 10, y + 10, 'Q', x + 20, y + 25, x + 10, y + 40]);
        }
        app.drawRoom(app.roomList.where({ id: room.get('s') })[0], x, y + 50, z);
    }
    if (room.get('w') !== "") {
        if (app.level === z) {
            app.paper.path(['M', x - 10, y + 10, 'Q', x - 25, y + 20, x - 40, y + 10]);
        }
        app.drawRoom(app.roomList.where({ id: room.get('w') })[0], x - 50, y, z);

    }
    if (room.get('u') !== "") {
        app.drawRoom(app.roomList.where({ id: room.get('u') })[0], x, y, z + 1);
    }
    if (room.get('d') !== "") {
        app.drawRoom(app.roomList.where({ id: room.get('d') })[0], x, y, z - 1);
    }
}

另外,您是否尝试使用以下方法清除画布:

app.paper.clearRect( 0, 0, app.paper.width, app.paper.height )

我发现这是最有效的方式。