2014-09-05 108 views
0

嗨,我是新来的铁轨,我想移动一个用户故事在其正确的列取决于其状态(待完成,正在进行中,..)与AJAX 我的节目模板包含四个div与归类(ToBeDone,INPROGRESS,ToBeVerified,已经完成)Rails ajax更新divs

我update.js.erb

$("div.<%= @user_story.state.underscore %>:first").append("<%= j render(@user_story)%>"); 

和我的更新动作

if [email protected]_story.users.include? current_user 
     @user_story.users << current_user 
    end 
    format.html { redirect_to @user_story.project, notice: 'User story was successfully updated.' } 
    format.json { render :show, status: :ok, location: @user_story } 
    format.js 

和我的user_story部分(这种形式是当用户选择状态提交)

<%= form_for [@project, user_story], remote: true do |f|%> 
    <div class="field" id='my_select_chzn'> 
    <%= f.label :state %> 
    <%= f.select :state, ['To be done', 'In progress', 'To be verified', 'Completed'], {:selected => user_story.state }, :id =>'select-state', :class => 'chosen-select'%> 
    </div> 
<%end%> 

请帮助,感谢和抱歉,这个长篇文章。

回答

2

几件事情you'l受益于:


阿贾克斯

当你提到你使用 “Ajax” 的,你必须记住,阿贾克斯被调用。您目前正在使用remote: true功能(完全正常),但同时提及您想要在选择框中调用change

这里的问题是,remote: true is rails UJS,并且脚本只在你的元素上触发了“动作”时触发。总之,对于表格,它只会在您提交表格时触发

这意味着你必须确保阿贾克斯居然触发:

#app/assets/javascripts/application.js 
$(document).on("change", "#select-state", function() { 
    $(this).parent().submit(); 
}); 

#app/views/controller/view.html.erb 
<%= form_for [@project, user_story], remote: true do |f|%> 
    <div class="field" id='my_select_chzn'> 
    <%= f.label :state %> 
    <%= f.select :state, ['To be done', 'In progress', 'To be verified', 'Completed'], {:selected => user_story.state }, :id =>'select-state', :class => 'chosen-select'%> 
    </div> 
<% end %> 

这应该引起你的Ajax请求。如果你想了解更多关于Ajax的知识,只需在这里评论我吧!


DIV

要更新您的DIV,你需要能够捕捉到Ajax响应。

这可以通过两种方式完成:通过使用JS进行捕获,或使用Rails UJS机制(这就是您正在做的)。当你调用update.js.erb,你创建你想在您的网页

上运行,这意味着你可能需要做这样的事情该JS:

#app/controllers/your_controller.rb 
... 
    def update 
    @user_story.users << current_user unless @user_story.users.include? current_user 
    respond_to do |format| 
     format.js 
     format.html { redirect_to @user_story.project, notice: 'User story was successfully updated.' } 
     format.json { render :show, status: :ok, location: @user_story } 
    end 
    end 

然后,在你的.js.erb文件,你会想要确保你的JS可以使用你的div元素。我看到你打电话给$("div.<%= @user_story.state.underscore %>:first") - 你需要确保这个div真的存在。

此外,我实际上说有4个独立的div是不好的。在保持DRY原则在Rails的核心,你最好保持一个DIV,用数据填充你想&造型不同的CSS类


状态机

您在使用“状态”几乎是一个state_machine的图片完美实现。

这是一个类型的编程功能(我相信电子过使用),给你的对象状态 - 这意味着,而不必设置了一系列的“弦”为您state列,你应该能够给它面向对象功能

我相信使用状态机宝石为Rails的人会给你的应用更加深入,更彻底实现你想要的功能:

所有这些(从我经验)以非常相似的方式工作 - 他们使用您在状态机中设置的相关数据更新中央state列。主要区别在于,您将在对象/模型级别处理事务,而不是设置字符串。

如果你look through the state_machine documentation会更容易理解,特别是你从实现这些宝石中获得的methods。这应该表现出你的模型的状态的面向对象的本质 - 你可以在下面执行:

#app/models/user_story.rb 
class UserStory < ActiveRecord::Base 
    include AASM 

    aasm do 
    state :to_be_done, :initial => true 
    state :in_progress 
    state :to_be_verified 
    state :completed 

    event :complete do 
     transitions :from => [:to_be_done, :in_progress, :to_be_verified], :to => :completed 
    end 

    event :progress do 
     transitions :from => [:to_be_done, :to_be_verified, :completed], :to => :in_progress 
    end 

    event :verify do 
     transitions :from => [:to_be_done, :in_progress, :completed], :to => :to_be_verified 
    end 
    end 
end 

这会给你打电话给其依附的UserStory对象的各种方法的能力:

@user_story = UserStory.find 1 

@user_story.state # -> "to be verified" 
@user_story.completed? #-> true/false 
@user_story.in_progress? #-> true/false 

@user_story.complete! # -> state = "completed" 

现在,这不会帮助您直接为您的对象设置“状态”。这将真正帮助的唯一途径是,如果你组织你的对象创建各种方法周围你会得到与使用state machine

一个很好的例子是的结果,如果你想送“集中“电子邮件 - 您可以使用以下内容:

#app/models/message.rb 
class Message < ActiveRecord::Base 
    after_create :send 

    private 

    def send 
     self.broadcast! 
    end 
end 

如果您想了解更多信息,请在评论中告诉我!

+0

非常感谢,正如你在我的js.erb文件中所说的,我以错误的方式选择了div,你的回答非常好,谢谢。 – 2014-09-05 16:06:58