1

我目前在联系人记录中嵌入了一个 Visualforce 页面,该页面显示所有活动的活动,并带有一个复选框,指示联系人是否是活动的成员(如果选中,则联系人是成员)。我还有一个命令按钮来保存更改。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:重复>

我的问题是,将复选框值传递给控制器​​的最佳方法是什么?理想情况下,我只想传递已更改的复选框,传递已从选中变为未选中的列表以及包含已从未选中变为选中的复选框的第二个列表。然后我可以插入和删除这些列表。

这是应该在复选框上使用 actionSupport 标签的情况吗?

<apex:actionSupport event="onChange" action="{!updateChangeList}" />
4

2 回答 2

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 列表并使用重载的构造函数“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

最终使用这两个列表 CHANGEDCONTACTLISTUNCHANGEDCONTACTLIST。您可以插入或删除 dml。

我相信这里没有使用 ActionSupport 标签,因为所有需要的值都将使用 ContactWrapper 列表的 getter 和 setter 来使用(读/写)。

public List<ContactWrapper> wrapper {get;set;}
于 2013-04-15T14:37:27.107 回答
1

整个集合将被发送回服务器(所有复选框的状态)。这在 Salesforce 和任何其他与 Web 相关的语言之间并没有太大的不同(例如,请参阅从多个复选框中获取 $_POST。主要区别在于通常您会使用名称以结尾的变量,[]而 SF 将使用带有递增数字的唯一名称名字)。

如果您真的想构建 2 个列表 - 也许是添加/删除 2 个隐藏文本字段内容的一些 javascript 魔术......但这有点混乱。

当表单将被提交并且您updateChangeList()被调用时,您可以迭代 CampaignWrappers 的集合并与之前的值进行比较。要么将先前的值存储在包装器中的另外 1 个变量中,并且不将其公开给用户,否则您仍然会根据 Campaign 中的内容知道:

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是一个不错的起点(我知道这很古老。基本上在这篇博文之前,我们必须为我们想要Boolean getSelected()void setSelected(Boolan b)每个变量编写在 VF 中使用)。

最后但并非最不重要的 -页面执行顺序的链接。

于 2013-04-15T11:15:23.143 回答