【发布时间】:2016-07-16 16:16:01
【问题描述】:
有没有一种方法可以在不重新加载页面的情况下重新加载视图中的实例变量?
我有一个 AJAX 帖子,它创建了一条新记录。我希望将该记录添加到现有的实例变量中。
所以我有一个诸如action 之类的操作,它处理我在action.html.erb 中的视图:
def action
@variable = Variable.where().to_a
end
然后我有一个执行诸如action2 之类的操作的 AJAX 请求:
def action2
@new_record = Variable.create(params)
respond_to do |format|
format.html
format.json {render :json => @new_record.to_json}
end
end
有没有办法刷新@variable 实例变量以包含新创建的记录?
我可以向action 发出另一个 AJAX 请求吗?如果是这样,我将如何检测action 中的 AJAX 请求?
我已经用request.xhr? 尝试过这个^^,但是在我执行一个JS .click() 之后它会抛出一个奇怪的StandardError?
我不确定我是否朝着正确的方向前进,但如果是,这里是我整理的所有代码...
我正在构建一个即时消息服务,我承认我完全是在拼凑一个原型。我知道有更简洁的方法可以处理高流量负载,但我现在正在制作原型。
视图代码看起来像这样...有:HTML 聊天框,我每 2 秒发出一次 AJAX 请求以查找新消息,在同一个函数中,我向上面称为 action 的内容发出 AJAX 请求(实际上命名不同),在“刷新”功能之后,我有一个.click() 功能来更新用户视图(刚刚提交的那个)。
<div id="wrapper">
<div id="menu">
<p class="welcome">Welcome, <b></b></p>
<p class="logout"><a id="exit" href="#">Exit Chat</a></p>
<div style="clear:both"></div>
</div>
<div id="chatbox">
<% @messages.each do |message| %>
<% if session[:email] == message.email %>
<!-- post to the right side -->
<div id="right-side">
<p>Email: <%= message.email %></p>
<p>Message: <%= message.message %></p>
</div>
<% else %>
<!-- post to the left side -->
<div id="left-side">
<p>Email: <%= message.email %></p>
<p>Message: <%= message.message %></p>
</div>
<% end %>
<% end %>
</div>
<form id="frm1" action="">
Message: <input id="message_input" type="text" name="fname"><br>
<!-- <input type="submit" value="Submit"> -->
<button name="submitmsg" type="submit" id="submitmsg">Try it</button>
</form>
</div>
<p id="demo"></p>
<script>
function retrieveMessages(){
var message;
$.ajax({
type:"GET",
url:"<%= get_messages_path %>",
dataType:"json",
data: {chat_id: <%= @message_info[:chat_id] %>,
last_message: <%= @messages.last.created_at.to_i %>},
success:function(data){
if (data != null){
console.log(data);
console.log(data.message);
message = data.message;
document.getElementById("chatbox").innerHTML += message + '<br>';
}
}
});
$.ajax({
type:"GET",
url:"<%= new_message_path %>",
dataType:"json",
success:function(data){
console.log("success!");
}
}
});
setTimeout(retrieveMessages, 2000);
}
$(document).ready(function(){
//get messages
setTimeout(retrieveMessages, 2000);
//send messages
$("#submitmsg").on('click', function(e){
e.preventDefault();
var x = document.getElementById("frm1"); //This is the form, and not the value of the textbox
var text = "";
var i;
for (i = 0; i < x.length ;i++) {
text += x.elements[i].value;
}
// document.getElementById("chatbox").innerHTML += text;
text_with_br = text + "<br>"
document.getElementById("chatbox").innerHTML += text_with_br;
document.getElementById("frm1").reset();
// console.log(document.getElementById("right"));
//Actual message is in 'text'
$.ajax({
url: "/messages",
method: "post",
data: { message: text,
chat_id: <%= @message_info[:chat_id] %>,
message_counter: <%= @message_info[:message_counter] + 1 %> },
dataType: "JSON",
success: function(response){
//do something,maybe notify user successfully posted their message
},
error: function(error){
console.log(error);
}
});
});
});
</script>
那么对于我的action 动作(实际上是new 动作,而我所谓的@variable 实际上是@messages:
def new
# debugger
# Message.create(:chat_id => 5)
if session[:email].nil?
#user not logged in
redirect_to new_session_path(:message => "need to login")
else
@user = User.where(:email => session[:email]).first
@message_info = Hash(email: @user.email, message_counter: 0, chat_id: Message.last.chat_id + 1)
@messages = Message.where(:chat_id => @message_info[:chat_id]).to_a
respond_to do |format|
format.html
format.json
end
end
end
那么执行AJAX请求获取最新消息(以便其他浏览器的查看者可以查看)的动作如下...
def get
@new_message = Message.where(["created_at > ?", Time.at(params[:last_message].to_i)]).first
respond_to do |format|
format.html
# format.json {render json: @new_message}
format.json {render :json => @new_message.to_json}
end
end
更新
@eggroll 建议的代码如下,但我遇到了引导问题
【问题讨论】:
-
我建议您将 div 附加到 ajax 成功回调的 $("#chatbox") 上。 div 包含响应 @variable
-
@power 它不会仍然只是向 HTML DOM 插入一条重复的消息吗?另外我遇到的主要问题是,当我在 AJAX GET 函数中传递参数
last_message: <%= @messages.last.created_at.to_i %>时,它只会发送自页面加载以来的最后一条消息——我需要一种将最新消息附加到@message的方法变量 -
在这种情况下,您可以通过new_message = Message.order("created_at").last 找到最后一条消息,然后将其created_at 与Time.at(params[:last_message].to_i 进行比较) 如果 new_message.created_at 更大,则表示您收到了 new_message,但如果相等,则表示您没有收到任何新消息,因此只需发送 nil 进行响应。有意义吗?
标签: javascript jquery ruby-on-rails ajax ruby-on-rails-4