渲染多杯咖啡的模式
Pattern to render multiple coffee
我有一个 task
模型,它与 user
和 project
模型相关。
当我 create/update 一项任务时,我需要在异步视图中进行更新,不仅针对任务 change/addition,还针对项目和用户信息(因为其中一些数据也可能会改变)。
我在控制器中有这个:
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
还有我的tasks/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 }) %>")
而且效果很好。我看到 2 个问题:
在我添加的 .js.coffee
的每个渲染中,我重复了太多代码。我复制完全相同的代码来更新项目和用户数据,任务更新,任务销毁,我会为可能影响用户和项目的新模型做同样的事情
在tasks/create中处理项目和用户数据似乎很奇怪。js.coffee
因此,我正在寻找更好的模式来处理这些东西,有什么想法吗?
编辑(澄清):
我认为实现这样的目标会更好:
tasks/create.js.coffee
# Update task table
$('#mytable').append("<%= j render(partial: 'tasks/task', locals: { t: @task }) %>")
UserData.refresh()
ProjectData.refresh()
但是,我不能那样做,因为我每次都需要渲染部分,所以我必须做一些奇怪的事情,比如将 html 部分传递给那些 refresh()
函数,并且这与以前的方式非常相似。
这只是我想到的一种方式,但我想听听您的想法。
您可以渲染属于不同控制器的 template/action。所以你可以保留 tasks/create.js.coffee 文件和所有其他使用相同代码的控制器操作(如用户和项目),在你的 respond_to 块中你将使用:
format.json { render 'tasks/create' }
您甚至可以渲染特定文件:
format.json { render file: "path/to/specific/file" }
这里是 link,其中包含有关 rails 中渲染的更多信息:http://guides.rubyonrails.org/layouts_and_rendering.html#rendering-an-action-s-template-from-another-controller
对于可能对此问题的答案感兴趣的任何人,我发现 Garber-Irish 模式 是解决我的问题的好方法。
您可以在此处阅读更多相关信息:
https://www.viget.com/articles/extending-paul-irishs-comprehensive-dom-ready-execution
甚至还有一个gem:https://github.com/tonytonyjan/gistyle
使用此模式,您可以为 HTTP 请求提供执行上下文。因此,例如,您可以在每个 js 控制器上有一个 afterCreate()
方法,并且根据创建 HTTP 请求的位置,您可以触发不同的事件。
这允许使用多态答案来更新视图。
我有一个 task
模型,它与 user
和 project
模型相关。
当我 create/update 一项任务时,我需要在异步视图中进行更新,不仅针对任务 change/addition,还针对项目和用户信息(因为其中一些数据也可能会改变)。
我在控制器中有这个:
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
还有我的tasks/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 }) %>")
而且效果很好。我看到 2 个问题:
在我添加的
.js.coffee
的每个渲染中,我重复了太多代码。我复制完全相同的代码来更新项目和用户数据,任务更新,任务销毁,我会为可能影响用户和项目的新模型做同样的事情在tasks/create中处理项目和用户数据似乎很奇怪。js.coffee
因此,我正在寻找更好的模式来处理这些东西,有什么想法吗?
编辑(澄清): 我认为实现这样的目标会更好:
tasks/create.js.coffee
# Update task table
$('#mytable').append("<%= j render(partial: 'tasks/task', locals: { t: @task }) %>")
UserData.refresh()
ProjectData.refresh()
但是,我不能那样做,因为我每次都需要渲染部分,所以我必须做一些奇怪的事情,比如将 html 部分传递给那些 refresh()
函数,并且这与以前的方式非常相似。
这只是我想到的一种方式,但我想听听您的想法。
您可以渲染属于不同控制器的 template/action。所以你可以保留 tasks/create.js.coffee 文件和所有其他使用相同代码的控制器操作(如用户和项目),在你的 respond_to 块中你将使用:
format.json { render 'tasks/create' }
您甚至可以渲染特定文件:
format.json { render file: "path/to/specific/file" }
这里是 link,其中包含有关 rails 中渲染的更多信息:http://guides.rubyonrails.org/layouts_and_rendering.html#rendering-an-action-s-template-from-another-controller
对于可能对此问题的答案感兴趣的任何人,我发现 Garber-Irish 模式 是解决我的问题的好方法。
您可以在此处阅读更多相关信息: https://www.viget.com/articles/extending-paul-irishs-comprehensive-dom-ready-execution
甚至还有一个gem:https://github.com/tonytonyjan/gistyle
使用此模式,您可以为 HTTP 请求提供执行上下文。因此,例如,您可以在每个 js 控制器上有一个 afterCreate()
方法,并且根据创建 HTTP 请求的位置,您可以触发不同的事件。
这允许使用多态答案来更新视图。