2011-12-13 62 views
6

我有一个使用自定义控制器的Visualforce页面,该控件用于编辑机会下的多个记录。自定义按钮或使用自定义控制器链接到Visualforce页面

我想创建一个自定义按钮或从商机链接到此Visualforce页面。

目前该链接看起来像:

/apex/ExamplePage?oppId={!Opportunity.Id} 

这在开发沙箱工作正常,但是当它被部署为托管包的一部分,链路断开的页面引用没有命名空间的前缀。

我发现上暗示,应该可以使用$页面引用Visualforce页面的URL在Force.com讨论板后Managed Package Redirecting Problem。例如。

{!URLFOR($Page.MyExamplePage,'',[objectId = campaign.id])} 

但这样做只能给我的语法错误:

Error: Field $Page.MyExamplePage does not exist. Check spelling.

有另一部分的职位,建议使用的Apex类和执行JavaScript来解决它。但在我看来,这只是将命名空间问题转移到Javascript中。

如何安全地引用Visualforce页面以在托管软件包的内部和外部工作?

+1

我在IdeaExchange上找到了[自定义按钮:在URL内容类型中暴露$页面](https://sites.secure.force.com/success/ideaView?id=08730000000aVIfAAM),这将很好的促进。 – 2011-12-15 00:56:52

回答

7

最好从Apex PageReference返回值来完成此操作。像这样将工作:

public PageReference returnPage() 
{ 
    return Page.MyExamplePage; 
} 

然后从Visualforce称之为:

<apex:commandButton value="Go To New Page" action="{!returnPage}"/> 

的顶点页的通话将处理翻译为您服务。

[编辑]

创建一个光秃秃的骨头Visualforce页面是这样的:

<apex:page standardController="Opportunity" extensions="TheController" action="{!returnPage}"/> 

添加上述returnPage()方法来一个新的TheController(或其他)类。它甚至不需要构造函数。这个类可以是这样的:

public TheController 
{ 
    public PageReference returnPage() 
    { 
     return Page.MyExamplePage; 
    } 
} 

然后从机遇设置页转到按钮和链接,并创建一个新的自定义Visualforce按钮,选择刚刚创建的新的一页。

这应该做到这一点。

+0

我需要从标准商机详细信息页面显示到Visualforce页面的链接。使用自定义的详细页面按钮,用户可以使用页面布局编辑器自由定位该按钮。你的建议是否与此类似?如果我的理解是正确的,我需要为returnPage()方法定制一个控制器,以及将CommandButton放在Opportunities详细信息页面上的方法。 – 2011-12-14 01:41:35

+0

将需要定制的Apex控制器。只要它在apex:页面定义中引用standardController =“Opportunity”和extensions =“NewCustomController”,您将会很好。我会修改我的答案以适应您的情况。直接从机会详情页面启动时,它涉及一个小技巧。 – Adam 2011-12-14 02:34:05

+0

谢谢,这是有效的。它在用户通过中间页面时会产生轻微的反弹,但它解决了PageReference问题。我能够通过使用将ApexPages.StandardController作为参数的构造函数向PageReference添加其他参数。我现在唯一担心的是我为每个自定义按钮添加了一个额外的页面和apex类。 – 2011-12-15 01:39:35

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的方法定义以获取页面引用。这样做可以让您在apex中获取页面的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()失败会发生什么,你很可能会希望有更多的错误处理。

0

在我看来,一个不太理想的选择是在每种情况下创建两个自定义按钮。一个带有托管包命名空间,另一个没有。

构建包时,可以选择正确的自定义按钮。

这种方法的一个问题是需要维护两个自定义按钮。

0

看来答案很简单/apex/package__Page由@zachelrath提供here。我可以在生产组织和开发中的托管软件包中证实这一点。