我有一个使用自定义控制器的Visualforce页面,该控制器用于编辑机会下的多个记录。
我想创建一个自定义按钮或从Opportunities到此Visualforce页面的链接。
目前链接如下:
/apex/ExamplePage?oppId={!Opportunity.Id}
这在开发沙箱中工作正常,但当它作为托管包的一部分部署时,链接会断开,因为页面引用没有名称空间前缀。
我在Force.com讨论区上发现帖子Managed Package Redirecting Problem,暗示应该可以使用$ Page来引用URL中的Visualforce页面。例如。
{!URLFOR($Page.MyExamplePage,'',[objectId = campaign.id])}
但这样做只会给我语法错误:
错误:字段$ Page.MyExamplePage不存在。检查拼写。
该帖子的另一部分建议使用Apex类和Execute Javascript来解决它。但在我看来,这只是将名称空间问题转移到Javascript中。
如何安全地引用Visualforce页面以在托管包内外工作?
答案 0 :(得分:7)
最好从Apex PageReference返回值执行此操作。这样的事情会起作用:
public PageReference returnPage()
{
return Page.MyExamplePage;
}
然后从Visualforce中调用它:
<apex:commandButton value="Go To New Page" action="{!returnPage}"/>
Apex Page调用将为您处理翻译。
[编辑]
像这样创建一个简单的Visualforce页面:
<apex:page standardController="Opportunity" extensions="TheController" action="{!returnPage}"/>
将上述returnPage()方法添加到新的TheController(或其他)类中。它甚至不需要构造函数。该课程可能如下所示:
public TheController
{
public PageReference returnPage()
{
return Page.MyExamplePage;
}
}
然后从商机设置页面转到按钮和链接,并创建一个新的自定义Visualforce按钮,选择刚刚创建的新页面。
应该这样做。
答案 1 :(得分:0)
您链接到的开发板上的帖子显示以下用于该按钮的javascript:
{!REQUIRESCRIPT("/soap/ajax/15.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/15.0/apex.js")}
var pageUrl = sforce.apex.execute("mynamespace.PageUrl", "getPageUrl", {objectId:"{!Campaign.Id}"});
window.location.href = pageUrl;
即。他们使用javascript在他们定义的类中调用webservice方法以获取页面引用。这样做可以让您在顶点获取页面的URL,托管包不会起到影响。
也就是说,第一个参数是完全限定的类名,所以你可能会检查错误的返回值(我不知道错误返回值,所以我假设它是null
这里):
// try the namespace first
var pageUrl = sforce.apex.execute("mynamespace.myClass", "getPageUrl", {objectId:"{!Campaign.Id}"});
if (pageUrl == null)
{
pageUrl = sforce.apex.execute("myClass", "getPageUrl", {objectId:"{!Campaign.Id}"});
}
window.location.href = pageUrl;
显然,您需要检查sforce.apex.execute()
失败时会发生什么,并且您可能需要更多错误处理。
答案 2 :(得分:0)
在我看来,一个不太理想的选择是在每种情况下创建两个自定义按钮。一个使用托管包命名空间,另一个没有。
构建包时,可以选择正确的自定义按钮。
这种方法的一个问题是需要维护两个自定义按钮。
答案 3 :(得分:0)
似乎答案只是{@ 1}}由@zachelrath提供here。我可以确认这在生产组织和开发中的托管包中都有效。