我目前在联系人记录中嵌入了一个Visualforce页面,该页面显示所有活动的广告系列,其中包含chexckbox,指示联系人是否是广告系列的成员(如果已选中,则联系人是其成员)。我还有一个命令按钮来保存更改。 visualforce代码使用 apex:repeat 生成,如下所示:
<apex:repeat value="{!campaignWrappers}" var="cm"> <div class="MailingRow"> <apex:outputText styleClass="CampaignLabel" value="{!cm.c.Name}" ></apex:outputText> <apex:inputCheckbox styleClass="CampaignCheck" value="{!cm.selected}" /> </div> </apex:repeat>
我的问题是,将复选框值传递给控制器的最佳方法是什么?理想情况下,我只想传递已更改的复选框,传递已从已检查到未选中的复选框列表以及包含已从未选中复选到已选中的复选框的第二个列表。然后我可以插入并删除这些列表。
是否应该在复选框上使用actionSupport标记?
<apex:actionSupport event="onChange" action="{!updateChangeList}" />
答案 0 :(得分:2)
您可以使用联系人对象的Wrapper类来存储联系人的当前状态和新状态,以检查联系人是否是广告系列的成员。
public class ContactWrapper
{
public Boolean checked{ get; set; }
public Contact con { get; set;}
public AccountSKUWrapper()
{
con = new Contact();
checked = false;
}
public ContactWrapper(Contact c)
{
con= c;
checked = c.selected;
}
}
使用选择的字段,我们可以确定联系人是否是Campaign的成员,并且包装器中的已检查变量有助于识别VF页面中给出的输入。创建ContactWrapper列表并使用Overloaded Contructor“ContactWrapper(Contact c)”初始化每个ContactWrapper对象。
<apex:repeat value="<ContactWrapper Object>" var="cm">
<div class="MailingRow">
<apex:outputText styleClass="CampaignLabel" value="{!cm.con.Name}" ></apex:outputText>
<apex:inputCheckbox styleClass="CampaignCheck" value="{!cm.checked}" />
</div>
</apex:repeat>
在保存按钮单击期间,请按照以下步骤操作:检查与所选字段不同的已检查变量的值。
Create 2 list **CHANGEDCONTACTLIST** and **UNCHANGEDCONTACTLIST** and then Loop through the list of ContactWrapper
begin loop
1.If checked differs then load **CHANGEDCONTACTLIST** with Contact Wrapper object as this need to be updated in Contact object; in order to update selected field of contact.
2.Else load **UNCHANGEDCONTACTLIST**.
end loop
最终使用这两个列表 CHANGEDCONTACTLIST 和 UNCHANGEDCONTACTLIST 。你可以插入或删除dml。
我认为这里没有使用ActionSupport标记,因为所有需要的值都将使用ContactWrapper列表的getter和setter来使用(读/写)。
public List<ContactWrapper> wrapper {get;set;}
答案 1 :(得分:1)
整个集合将被发送回服务器(所有复选框的状态)。 Salesforce和任何其他与Web相关的语言之间没有太大区别(例如,请参阅Get $_POST from multiple checkboxes。主要区别在于,通常使用名称以[]
结尾的变量,SF将使用唯一的名称在名称的某处递增数字。)
如果你真的想要建立2个列表 - 可能是添加/删除2个隐藏文本字段内容的一些javascript魔法......但这有点混乱。
当提交表单并调用updateChangeList()
时,您可以迭代CampaignWrappers的集合并与之前的值进行比较。将先前的值存储在包装器中的另外1个变量中。不要将其暴露给用户,或者您仍然会根据广告系列中的内容了解:
Set<Id> campaignsToBeAddedTo = new Set<Id>();
Set<Id> campaignsToBeRemovedFrom = new Set<Id>();
for(CampaignMember cm : campaignWrappers){
if(cm.selected && cm.c.CampaignMembers.isEmpty(){
// is ticket but wasn't a member before
campaignsToBeAddedTo.add(cm.c.Id);
} else if (!cm.selected && !cm.c.CampaignMembers.isEmpty()){
// not ticked but used to be a member
campaignsToBeRemovedFrom.add(cm.c.Id);
}
}
你甚至可以优化它(比如把isEmpty()检查到辅助变量)。或者阅读有关可能产生“副作用”的setter方法。毕竟,当表单数据被反序列化时,无论如何都会为你运行这样的循环。 http://blogs.developerforce.com/developer-relations/2008/06/property-access.html是一个很好的起点(它很古老,我知道。基本上在这篇博文之前我们必须为我们想要在VF中使用的每个变量编写Boolean getSelected()
和void setSelected(Boolan b)
。
最后但并非最不重要 - 指向page execution order的链接。