javascript 功能不可见?不会被第二次调用
javascript function not visible? does not get called a second time
这可能是一个新手问题,请耐心等待。我正在对 Rails 4、Javascript 和 Raphael 上的 Ruby 进行一些修改。我也在使用 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);
如您所见,我的目的是清理 canvas 并使用不同的参数重绘所有内容。新参数没问题,我检查了按下第二个按钮时以下内容是否有效,有效地使 canvas 保持干净,除了一个孤独的圆圈:
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
它们链接到 2 个独立的控制器方法:
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
然后views包含以下调用(其实一样,只是参数不同):
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);
}
}
}
});
您第二次尝试绘制任何东西都失败了,因为您的 Backbone 模型上的 drawn
变量已设置为 true。下面的代码指定 not 在特定 属性 为真时绘制:
if (room.get('drawn') == false) {
room.set('drawn', true);
// your room drawing code is here
}
如果您想保留布尔值 drawn 标志,请将整个 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);
}
}
此外,您是否尝试过使用以下方法清除 canvas:
app.paper.clearRect( 0, 0, app.paper.width, app.paper.height )
我发现这是最有效的方法。
这可能是一个新手问题,请耐心等待。我正在对 Rails 4、Javascript 和 Raphael 上的 Ruby 进行一些修改。我也在使用 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);
如您所见,我的目的是清理 canvas 并使用不同的参数重绘所有内容。新参数没问题,我检查了按下第二个按钮时以下内容是否有效,有效地使 canvas 保持干净,除了一个孤独的圆圈:
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
它们链接到 2 个独立的控制器方法:
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
然后views包含以下调用(其实一样,只是参数不同):
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);
}
}
}
});
您第二次尝试绘制任何东西都失败了,因为您的 Backbone 模型上的 drawn
变量已设置为 true。下面的代码指定 not 在特定 属性 为真时绘制:
if (room.get('drawn') == false) {
room.set('drawn', true);
// your room drawing code is here
}
如果您想保留布尔值 drawn 标志,请将整个 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);
}
}
此外,您是否尝试过使用以下方法清除 canvas:
app.paper.clearRect( 0, 0, app.paper.width, app.paper.height )
我发现这是最有效的方法。