简体   繁体   English

自定义按钮或使用自定义控制器链接到Visualforce页面

[英]Custom Button or Link to a Visualforce page with a custom controller

I have a Visualforce page using a custom controller that is used to edit multiple records under an opportunity. 我有一个Visualforce页面使用自定义控制器,用于编辑机会下的多个记录。

I'd like to create a custom button or link from Opportunities to this Visualforce page. 我想创建一个从Opportunities到此Visualforce页面的自定义按钮或链接。

Currently the link looks like: 目前链接如下:

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

This works fine in the development sandbox, but when it is deployed as part of a managed package the link breaks as the page reference doesn't have the namespace prefix. 这在开发沙箱中工作正常,但是当它作为托管包的一部分部署时,链接会断开,因为页面引用没有名称空间前缀。

I found the post Managed Package Redirecting Problem on the Force.com Discussion Boards which implied it should be possible to use $Page to reference the Visualforce page in the URL. 我在Force.com讨论板上发现了托管包重定向问题 ,暗示应该可以使用$ Page来引用URL中的Visualforce页面。 Eg 例如

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

But doing so only gives me the syntax error: 但这样做只会给我语法错误:

Error: Field $Page.MyExamplePage does not exist. 错误:字段$ Page.MyExamplePage不存在。 Check spelling. 检查拼写。

There is another part to the post that suggests using an Apex class and Execute Javascript to work around it. 该帖子的另一部分建议使用Apex类和Execute Javascript来解决它。 But it appears to me that this has just moved the namespace issue into the Javascript. 但在我看来,这只是将名称空间问题转移到了Javascript中。

How can I safely reference the Visualforce page to work both inside and outside a managed package? 如何安全地引用Visualforce页面以在托管包内外工作?

Best to do this from an Apex PageReference return value. 最好从Apex PageReference返回值执行此操作。 Something like this will work: 这样的东西会起作用:

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

Then call this from Visualforce: 然后从Visualforce调用它:

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

The Apex Page call will handle the translation for you. Apex Page调用将为您处理翻译。

[EDIT] [编辑]

Create a bare bones Visualforce page like this: 像这样创建一个简单的Visualforce页面:

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

Add the above returnPage() method to a new TheController (or whatever) class. 将上面的returnPage()方法添加到新的TheController(或其他)类中。 It doesn't even need a constructor. 它甚至不需要构造函数。 The class can look like this: 该类可以如下所示:

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

Then from the Opportunity settings page go to Buttons and Links and create a new custom Visualforce button selecting the new page you just created. 然后从商机设置页面转到按钮和链接,并创建一个新的自定义Visualforce按钮,选择刚刚创建的新页面。

That should do it. 应该这样做。

It seems the answer is simply /apex/package__Page as provided here by @zachelrath. 看来答案很简单/apex/package__Page为提供在这里通过@zachelrath。 I can confirm this works in managed packages in production orgs as well as in development. 我可以确认这在生产组织和开发中的托管包中都有效。

The post on the developer boards that you've linked to shows the following javascript being used for the button: 您链接到的开发人员主板上的帖子显示以下用于该按钮的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;

ie they're using javascript to call a webservice method in the class they've defined in order to get the page reference. 即他们使用javascript在他们定义的类中调用webservice方法以获取页面引用。 Doing this would allow you to get the URL of the page in apex, where the managed package won't play an impacting part. 这样做可以让您在顶点获取页面的URL,其中托管包不会起到影响。

That said, the first parameter is the fully-qualified class name, so you could probably check the return value for an error (I don't know the error return value, so I'm assuming it's null here): 也就是说,第一个参数是完全限定的类名,所以你可能会检查错误的返回值(我不知道错误返回值,所以我假设它在这里为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;

Obviously you need to check what happens when sforce.apex.execute() fails, and you'll likely want some more error handling. 显然,您需要检查sforce.apex.execute()失败时会发生什么,并且您可能需要更多错误处理。

It occurred to me that one less than ideal option would be to create two custom buttons in each case. 在我看来,一个不太理想的选择是在每种情况下创建两个自定义按钮。 One with the managed package namespace and one without. 一个使用托管包命名空间,另一个没有。

When building the package the correct custom button could be selected. 构建包时,可以选择正确的自定义按钮。

One issue with this approach is the need to maintain two custom buttons. 这种方法的一个问题是需要维护两个自定义按钮。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM