在不少场景下,需要一个拨动功能(toggle)的按钮,譬如在 todolist 中,勾选中,即代表任务“完成”;对已经勾选中的任务,取消勾选,则代表任务恢复为为“未完成”的状态。 还有其他类似是否缴费、是否已发送提醒以及很多二选一状态的功能设置都需要拨动功能设置。 就上述,需要一个简单的解决方案。
model: 在模型属性层面,需要一个类似二选一的属性,譬如 todo.status 或者 task.completed?
view: 在前端,需要一个简单的方案,下拉选框,通常使用 link_to 可以很方便的解决点击不同下拉选项进行不同操作的问题。而对于拨动功能按钮,最简单的方案是 单选框。 前端代码如下:
<input name="check_completed_<%= todo_item.id %>" type="checkbox" data-remote="true" data-url="<%= toggle_todolist_path(todo_item) %>" value="1" data-method="post" ><i class="fas fa-check"></i>
以上是未选中状态的代码,选中状态下的的前端如下:
<input name="check_completed_<%= todo_item.id %>" checked type="checkbox" data-remote="true" data-url="<%= completed_todolist_path(todo_item) %>" data-method="post" ><i class="fas fa-check"></i>
未选中状态的前端代码,少了 value,多了 checked。后端控制器主要是通过 value 的值判断前端选中或未选中的状态。
routes(路由设置):
resources :todolists do
member do
post "toggle" => "todolists#toggle"
end
end
在路由中,设置一个拨动 toggle 的路由,对应的控制器方法是 toggle
controller: 控制器读取前端的 input 的 value 值,并根据 value 改变模型的属性值。
def toggle
@todo_item = Todolist.find(params[:id])
input_name = "check_completed_" + @todo_item.id.to_s // input_name即前端单选框的名字,对应的前端代码 input name="check_completed_<%= todo_item.id %>"
if params[input_name] == "1"
@todo_item.update_attribute(:status, 'completed')
redirect_to todolists_path
else
@todo_item.update_attribute(:status, 'uncompleted')
redirect_to todolists_path
end
end
上述解决方案,前端通过 data-remote data-url data-method 的 Unobtrusive JavaScript 的远程元素方法,即 rails ujs 方法,实现了 input 一行代码将前端设置传递到后端控制器,简便便捷。 相关资源网址: