6

我正在尝试SearchContainer在我的 liferay 应用程序中使用。目前我必须使用 JSP Scriplets在标签中设置结果。<liferay-ui:search-container-results>这是到目前为止的片段:

<liferay-ui:search-container emptyResultsMessage="there-are-no-courses" delta="5">
    <liferay-ui:search-container-results>
        <%
            List<Course> tempResults = ActionUtil.getCourses(renderRequest);

            results = ListUtil.subList(tempResults, 
                                   searchContainer.getStart(), 
                                   searchContainer.getEnd());

            total = tempResults.size();
            pageContext.setAttribute("results", results);
            pageContext.setAttribute("total", total);
        %>
    </liferay-ui:search-container-results>

    <liferay-ui:search-container-row ...></liferay-ui:search-container-row>

    <liferay-ui:search-iterator />

</liferay-ui:search-container>

现在,我想将这些脚本更改为 EL。我发现了一篇关于同一问题的帖子,但那是使用Spring MVC. 而且我不知道在该问题的答案中给出的以下行在portlet中写在哪里:

SearchContainer<Book> searchContainer = new SearchContainer<Book>(renderRequest, renderResponse.createRenderURL(), null, "there are no books");

无法在我的 portlet 操作中编写它,因为我的操作中的参数是ActionRequestand ActionResponse,它没有定义 method createRenderURL()。我将如何获得PortletURL

我应该在哪里写上面的语句?目前,我正在以返回此页面的相同操作进行写作。我做对了吗?这是我从同一页面触发的操作,如下所示search-container

public void addCourse(ActionRequest request, ActionResponse response) 
        throws Exception {

    ThemeDisplay themeDisplay = 
            (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);

    Course course = ActionUtil.courseFromRequest(request);

    List<String> errors = new ArrayList<String>();

    if (CourseRegValidator.validateCourse(course, errors)) {
        CourseLocalServiceUtil.addCourse(course, themeDisplay.getUserId());
        SessionMessages.add(request, "course-added-successfully");

        // I thought I might put it here.
        // But I don't know what to pass as `PortletURL` in constructor of SearchContainer
    } else {
        SessionErrors.add(request, "fields-required");
    }
}

我希望,每次Course添加 a 时,它都会呈现在我的搜索容器中,在我触发addCourse操作的同一页面上。

是的,我的 portlet 扩展了MVCPortlet.


更新

好的,我想出了一些部分。

  • 第一次加载 portlet 时,我可以覆盖doView我的 portlet 中的方法,然后SearchContainerrenderRequest其中添加 ,因为我可以在doView.
  • 但同样,当我继续editCourse()采取行动时,我正在做一个response.setRenderParameter(),将它发送到另一个 jsp 页面。在那个 JSP 页面中,我正在触发一个updateCourse()动作。
  • 现在,从updateCourse()行动开始,我再次使用response.setRenderParameter()将它发送到原始 JSP 页面,我正在使用Search Container。但是现在,由于它没有通过doView()方法,我无法创建SearchContainer并将其添加到请求中。

那么,这里有什么解决方法吗?如何确保我在方法中设置的属性renderRequestdoView方法中可用updateCourse?我知道这听起来不切实际,因为这完全是一个新要求,但还有其他方法吗?

我能想到的一种解决方法是在更大的范围内设置属性,例如sessioncontext代替renderRequest. 但是,我在其他任何地方都不需要该属性。所以,我认为这不合适。

有什么输入吗?


更新 2

刚才,我用过:

actionResponse.setPortletMode(PortletMode.VIEW);

代替:

actionResponse.setRenderParameter("jspPage", jspPage);

它起作用了,因为它现在通过doView()方法。只想问,这样合适吗?当我们将渲染参数设置到同一个 JSP 页面时,两种方法有什么区别,doView方法重定向到哪里?


我当前的doView方法如下所示:

@Override
public void doView(RenderRequest renderRequest, RenderResponse renderResponse) 
        throws IOException, PortletException {

    SearchContainer<Course> searchContainer = 
            new SearchContainer<Course>(renderRequest, renderResponse.createRenderURL(), null, "there-are-no-courses");

    searchContainer.setDelta(5);
    List<Course> tempResults = ActionUtil.getCourses(renderRequest);

    List<Course> results = ListUtil.subList(tempResults, 
                                    searchContainer.getStart(), 
                                    searchContainer.getEnd());

    searchContainer.setTotal(tempResults.size());
    searchContainer.setResults(results);

    renderRequest.setAttribute("searchContainer", searchContainer);
    super.doView(renderRequest, renderResponse);
}
4

1 回答 1

3

评论转换为答案:

  1. 每当您呈现一个 portlet 时,它都是通过 doView 方法呈现的,而不是直接通过作为 portlet 生命周期的一部分的 action 方法呈现。
  2. 在 doView 中设置为 renderRequest.setAttribute("searchResults", course) 和 renderRequest.setAttribute("searchTotal", total) 的结果和总计将在 view.jsp 中作为 ${searchResults} 和 ${searchTotal} 可用。
  3. 每次执行任何操作时,都会调用 doView,然后再次设置 searchResults 和 searchTotal 并显示。
  4. 或者您可以按照您在问题中链接的答案searchContainer中的说明在 doView 方法本身中设置。
于 2013-07-30T10:33:33.037 回答