我想知道是否可以在Rhodes
的edit.erb
页面中使用类似form_for
的标记,而不是html标记。因为我有一个Counter
模型,它有两个属性,我想根据值旁边的按钮分别更新它们。我能够使用<%= form.submit 'up_a' %>
&检查在更新方法中按下了哪个按钮,如:
def update
@counter = Counter.find(params[:id])
if params[:commit] == 'up_a'
update_attri1 # simple increment method for attrib 1
elsif params[:commit] == 'up_b'
update_attri2 # simple increment method for attrib 2
end
end
并调用该方法来更新该值。
所以我想更多地控制我想要更新的属性点击表格。我在罗德斯有没有办法做到这一点?
编辑:
一般的问题似乎是,您希望在一个表单中有两个提交按钮,每个按钮应该做两件稍微不同的事情。
如果您只有两个不同的值,每个值都有一个提交按钮,那么最简单的解决方案就是制作两个表单,它们都调用update
def(通过它们的action属性),但每个表单都有查询参数的特定值(在本例中为"提交")。这些呼叫将具有以下形式:
<form method="POST" class="myForm" action="<%=url_for :controller => :Counter, :action => :update, :query => {:commit => 'up_a'}%>">
然而,如果你只想要一个表单(可能还有许多其他输入值),有几种不同的方法可以做到这一点。在下面你会看到一种方法的详细实现。
在这个解决方案中,您的按钮不应该是提交按钮,而是常规按钮(确切地说,它们是如何使用jQueryMobile制作的)。
为了使这个解决方案发挥作用,您需要使用一些javascript。因此,您应该将以下javascript函数添加到application.js
中,并将其包含在layout.erb
中。
function submitForm(formClass){
var activeForm = 'div.ui-page-active '+formClass;
$(activeForm).submit();
}
function callCounterSetUpdateAction(c){
$.get('/app/Counter/setUpdateAction', { commit: c});
}
现在我们已经准备好了所需的javascript函数,让我们来看看edit.erb
。
在这个例子中,Counter有三个不同的属性:a、b和c。然而,我们首先只关注a和b。
edit.erb
文件中的表单应该与下面的实现类似。请注意,表单实际上没有提交按钮(正如我们稍后将看到的,提交实际上是通过我们的javascript函数submitForm(formClass)
进行的)。
<form method="POST" class="myForm" action="<%= url_for :action => :update %>">
<input type="hidden" name="id" value="<%= @counter.object %>"/>
<div data-role="fieldcontain">
<label for="counter[a]" class="fieldLabel">A</label>
<input type="text" id="counter[a]" name="counter[a]" value="<%= @counter.a %>" <%= placeholder( "A" ) %> />
</div>
<div data-role="fieldcontain">
<label for="counter[b]" class="fieldLabel">B</label>
<input type="text" id="counter[b]" name="counter[b]" value="<%= @counter.b %>" <%= placeholder( "B" ) %> />
</div>
<div data-role="fieldcontain">
<label for="counter[c]" class="fieldLabel">C</label>
<input type="text" id="counter[c]" name="counter[c]" value="<%= @counter.c %>" <%= placeholder( "C" ) %> />
</div>
<a data-role="button" data-transition="none" href="javascript:callCounterSetUpdateAction('up_a');">Update A</a>
<a data-role="button" data-transition="none" href="javascript:callCounterSetUpdateAction('up_b');">Update B</a>
</form>
既然我们已经定义了我们的视图(edit.erb
),让我们来看看我们需要控制器的定义。
首先,从按钮上的href
属性可以看出,一旦我们按下按钮,实际发生的事情是它调用一个javascript函数,该函数反过来调用控制器中的以下def
:
def setUpdateAction
$pressedButton = @params['commit']
WebView.execute_js("submitForm('.myForm');")
end
此def
的目的是存储我们从按钮发送的参数,然后在活动页面上提交表单。请注意,我们在上面显示的表单中添加了一个名为myForm
的class
。您还应该注意,我们通过在jQuery选择中将'div.ui-page-active '
添加到我们的formClass
中,确保只选择活动页面上的表单。
最后,让我们看看update
定义应该是什么样子的:
def update
@counter = Counter.find(@params['id'])
c = @params['counter']
if @counter
if $pressedButton == 'up_a'
# Update value A.
@counter.update_attributes(
{"a" => c['a']}
)
elsif $pressedButton == 'up_b'
# Update value B.
@counter.update_attributes(
{"b" => c['b']}
)
end
end
redirect :action => :index
end
这里需要注意的是,我们根据通过setUpdateAction
分配的$pressedButton
变量来选择要更新的属性。作为最后的注释,我们还可以更新多个属性,如下所示(其中我们还更新了"c"属性)。
@counter.update_attributes(
{"b" => c['b'],"c" => c['c']}
)