asc*_*man 6 javascript ruby-on-rails coffeescript ruby-on-rails-4
我有一个task这是关系到模型user和project模型.
当我创建/更新任务时,我需要在视图异步中进行更新,不仅用于任务更改/添加,还包括项目和用户信息(因为某些数据也可能会更改).
我在控制器中有这个:
def create
@task = Task.new(params[:task])
@project = Project.find(params[:project_id])
respond_to do |format|
if @task.save
format.html { redirect_to @task, notice: 'Task was successfully created.' }
format.json { render json: @task, status: :created, location: @task }
else
format.html { render action: "new" }
format.json { render json: @task.errors, status: :unprocessable_entity }
end
end
end
Run Code Online (Sandbox Code Playgroud)
我的任务/ create.js.coffee
# Update task table
$('#mytable').append("<%= j render(partial: 'tasks/task', locals: { t: @task }) %>")
# Update user data
$('.user-data').html("<%= j render(partial: 'users/user_widget', locals: { u: current_user }) %>")
# Update project data
$('.project-data').html("<%= j render(partial: 'projects/project_widget', locals: { p: @project }) %>")
Run Code Online (Sandbox Code Playgroud)
而且效果很好.我看到2个问题:
在.js.coffee我添加的每个渲染中,我都在重复代码.我复制完全相同的代码来更新项目和用户数据,任务更新,任务销毁,我会对可能影响用户和项目的新模型做同样的事情
处理tasks/create.js.coffee中的项目和用户数据似乎很奇怪
因此,我正在寻找一个更好的模式来处理这些东西,任何想法?
编辑(澄清): 我认为实现这样的事情会更好:
任务/ create.js.coffee
# Update task table
$('#mytable').append("<%= j render(partial: 'tasks/task', locals: { t: @task }) %>")
UserData.refresh()
ProjectData.refresh()
Run Code Online (Sandbox Code Playgroud)
但是,我不能这样做,因为我需要每次都渲染部分,所以我必须做一些奇怪的事情,比如将html部分传递给那些refresh()函数,它将与之前的方式完全相同.这只是我想到的一种方式,但我想听听你的想法.
对于任何可能对此问题的答案感兴趣的人,我发现加伯-爱尔兰模式是解决我的问题的一个很好的解决方案。
您可以在这里阅读更多相关信息: https: //www.viget.com/articles/extending-paul-irishs-compressive-dom-ready-execution
甚至还有一个宝石: https: //github.com/tonytonyjan/gistyle
使用此模式,您可以拥有 HTTP 请求的执行上下文。例如,您可以afterCreate()在每个 js 控制器上拥有一个方法,并且根据创建 HTTP 请求的位置,您可以触发不同的事件。
这允许使用多态答案来更新视图。