如何通过Trigger将带业务数据的PDF关联到Opportunity及空白问题排查
问题修复方案
核心问题原因
- 上下文隔离问题:你在future方法中手动实例化的
OpportunityPdfController和VF页面渲染时系统自动创建的控制器是完全独立的两个实例,前者填充的数据无法传递给后者,VF页面读取的是全新实例中未赋值的pricingDetails,因此内容为空。 - 空集合未初始化:
OpportunityPdfController中的pricingDetails属性仅声明未初始化,直接调用add()方法会触发空指针异常,也是数据无法正常加载的原因之一。 - 字段拼写错误:Attachment对象的关联父记录字段是
ParentId,你的代码中写为ParenId,会导致附件关联失败。 - 触发器事件不匹配:触发器声明仅支持
after insert事件,但判断逻辑包含after update,插入场景下逻辑不会执行。
修复代码
1. 修正触发器
// 新增after update事件支持 trigger OpportunityTrigger on Opportunity (after insert, after update) if(trigger.isAfter && (trigger.isInsert || trigger.isUpdate)) { opportunityTriggerHelper.attachFileToOpportunityRecord(trigger.new); }
2. 修正Helper类
private void attachFileToOpportunityRecord(List<Opportunity> lstOpp) { List<Id> oppListIdsForAttach = new List<Id>(); for(Opportunity opp : lstOpp) { oppListIdsForAttach.add(opp.Id); } attachFileToOpportunities(oppListIdsForAttach); } @future(callout=true) private static void attachFileToOpportunities(List<Id> OpportunityIds) { List<Attachment> attachList = new List<Attachment>(); for(Id oppId : OpportunityIds) { // 给VF页面传递oppId参数,不需要手动实例化控制器 PageReference pdfPage = Page.PdfAttachmentForOpp; pdfPage.getParameters().put('oppId', oppId); Blob pdfBody = pdfPage.getContent(); Attachment attach = new Attachment(); attach.Body = pdfBody; attach.Name = 'Pdf file'; attach.IsPrivate = false; // 修正拼写错误 attach.ParentId = oppId; attachList.add(attach); } insert attachList; }
3. 修正VF页面控制器
public with sharing class OpportunityPdfController { public List<PricingDetailWrapper> pricingDetails {get;set;} // 构造函数:VF页面加载时自动获取参数,初始化数据 public OpportunityPdfController() { // 初始化集合,避免空指针 pricingDetails = new List<PricingDetailWrapper>(); String oppId = ApexPages.currentPage().getParameters().get('oppId'); if(oppId != null) { getData(oppId); } } public void getData(Id opportunityId) { List<Pricing_Detail__c> pdList = [ SELECT basePrice FROM Pricing_Detail__c WHERE OpportunityId =: opportunityId ]; for(Pricing_Detail__c pd : pdList) { PricingDetailWrapper pdw = new PricingDetailWrapper(); pdw.basePrice = pd.basePrice; pricingDetails.add(pdw); } } public class PricingDetailWrapper { public String basePrice {get;set;} } }
4. VF页面无需修改,保持原有逻辑即可。
内容的提问来源于stack exchange,提问作者ChrisB
相关产品推荐
相关产品推荐

