portal

JSR168将Portal 的组成分为三部份 (1) Portal Server (2) Portlet Container (3) Portlet。

Portal Server的定义
建立在HTTP Server上。负责接收HTTP请求,调用Portlet,并将Portlet产生的内容聚集到Portal页面返回给用户。(Portal Server有时简称Portal)

Portlet Container 的定义
Portal Container:管理Portlet的生命周期并且提供其运行所需要的必要环境。同时也提供Portlet相关信息的存储。一个Portlet container 接收到来自Portal 的请求后,接着将这个请求传递给存在Container 的Portlet 执行。Portlet Container 没有义务去组合Portlets 产生的信息內容,这个工作必须由Portal (即Portal Server)来处理。Portal 和Portlet Container 可以放在一起视为同一个系统的组件,或者分开成为两个独立的组件。

Portlet的定义
一个 Portlet 是以 Java 技术为技术的 Web 组件,由 Portlet Container 所管理,专门处理客户的 request 以及产生各种动态的信息内容。Portlets 为可插式 ( pluggable ) 的客户界面组件,提供呈现层成为一个信息系统。
这些由 portlet 产生的内容也被称为片段 (fragment),而片段是具有一些规则的Markup( HTML、XHTML、WML ),而且可以和其他的片段组合而成一个复杂的文件。而 Portlet 中的内容正常来说是与其他 Portlet 的内容聚合而成为一个 Portal 网页。而 Portlet 的生命周期是被 Portlet Container 所管理控制的。

客户端和 portlets 的互动是由 portal 通过典型的 request/response 方式实现,正常来说,客户会和 portlets 所产生的内容互动,举例来说,根据下一步的连接或者是确认送出的表单,结果 portal 将会接收到 portlet 的动作,将这个处理状况转向到目标 portlet。这些 portlet 内容的产生可能会因为不同的使用者而有不同的变化,完全是根据客户对于这个 portlet 的设置。

Portlet生命周期
Portlet接口的四个方法构成一个完整的生命周期:
public void init(PortletConfig config) throws PortletException;
     由Portlet容器调用,在将Portlet放入服务区前调用。Portlet容器在初始Portlet后,直接调用这个方法。
public void processAction (ActionRequest request, ActionResponse response) throws PortletException, java.io.IOException;
     由Portlet容器调用,用来处理action request。
public void render (RenderRequest request, RenderResponse response) throwsPortletException, java.io.IOException;
     由Portlet容器调用,用来生成输出。
public void destroy() ;
     将Portlet从服务区中删除。

一个Portal处理流程

1.  一个客户端(例如:一个web浏览器)在被验证之后向Portal发出HTTP请求;

2.  Portal(或称为Portal Server)接收到请求;

3.  Portal判断请求是否包含与组成门户网站网页的portlet有关的动作;

4.  如果存在与某个portlet相关的动作,Portal请求portlet容器调用portlet处理动作;

5.  Portal通过portlet容器调用portlet,获得被包含在产生的门户网站网页中的内容片段;

6.  Portal将portlet产生的结果聚集于门户网站的网页,然后将网页返回至客户端。

在下图中需要注意的是Portal服务器是建立在Http服务器的基础上的。Portal服务器不可独立的运行。

08-15
### 三级标题:Portal 的定义与应用场景 在前端开发中,“Portal”通常指的是将某个组件或内容渲染到当前组件树之外的一个机制。这种机制允许开发者将某些 UI 元素(如模态框、弹出菜单、提示框等)渲染到页面的任意位置,而不仅仅局限于当前组件的 DOM 结构中。这种技术在 Angular 和 React 等主流框架中都有实现。 在 Angular 中,`@angular/cdk/portal` 提供了 `Portal` 和 `PortalOutlet` 这两个核心概念,用于实现在框架执行上下文之外动态创建子视图的功能。开发者可以通过 `ComponentPortal` 或 `TemplatePortal` 来封装需要渲染的内容,并将其挂载到指定的 `PortalOutlet` 中。为了简化开发流程,Angular CDK 还提供了 `CdkPortal` 和 `CdkPortalOutlet` 指令,隐藏了底层实现细节,使得开发者只需简单的调用即可完成 Portal 的创建和挂载 [^1]。 在 React 中,`ReactDOM.createPortal()` 是官方提供的用于实现 Portal 的 API。通过该方法,可以将某个 React 组件的内容渲染到指定的 DOM 节点中,而不会受到父组件的样式或布局限制。这种方式特别适用于需要脱离当前组件层级结构的 UI 元素,例如全屏遮罩、全局提示等 [^2]。 ### 三级标题:Portal 的工作原理 在 Angular 中,`Portal` 的核心机制是通过 `ViewContainerRef` 和 `ComponentFactoryResolver` 来动态创建组件实例,并将其附加到指定的 `PortalOutlet` 容器中。`PortalOutlet` 可以是一个 DOM 元素,也可以是一个已经存在的 Angular 组件容器。通过这种方式,Portal 可以实现跨组件层级的渲染。 在 React 中,`createPortal` 的实现依赖于 React 的渲染机制。当调用 `ReactDOM.createPortal(child, container)` 时,React 会将 `child` 渲染为 `container` 节点的子节点,而不是当前组件的父节点。这意味着 Portal 渲染的内容虽然在 DOM 结构上脱离了当前组件的层级,但在 React 的虚拟 DOM 中仍然属于当前组件的树结构 [^2]。 ### 三级标题:Portal 的优势与注意事项 Portal 的主要优势在于它能够将特定的 UI 元素渲染到页面的任意位置,从而避免样式污染和布局限制。例如,在模态框或弹出菜单的实现中,如果这些元素被嵌套在多个父组件中,可能会受到父组件的 `overflow` 或 `z-index` 样式的影响,导致显示异常。通过 Portal,可以将这些元素直接渲染到 `<body>` 下,从而避免这些问题。 然而,使用 Portal 时也需要注意一些潜在的问题。例如: - **样式隔离**:由于 Portal 渲染的内容可能位于页面的不同位置,因此需要确保其样式不会与其他部分产生冲突。 - **事件冒泡**:Portal 渲染的内容虽然在 DOM 结构上独立,但事件仍然会按照正常的 DOM 结构进行传播。因此,需要注意事件的捕获和阻止冒泡。 - **性能优化**:频繁地创建和销毁 Portal 可能会影响性能,因此建议在必要时才使用 Portal,并合理管理其生命周期 [^1][^2]。 ### 三级标题:Portal 的实际应用示例 #### Angular 中的 Portal 示例 在 Angular 中,可以使用 `ComponentPortal` 来创建一个 Portal,并将其挂载到指定的 `PortalOutlet` 上。以下是一个简单的示例代码: ```typescript import { ComponentPortal } from '@angular/cdk/portal'; import { Component, ViewChild, ViewContainerRef } from '@angular/core'; @Component({ selector: 'app-root', template: ` <div> <button (click)="attachPortal()">Attach Portal</button> <ng-template #portalOutlet></ng-template> </div> ` }) export class AppComponent { @ViewChild('portalOutlet', { read: ViewContainerRef }) portalOutlet!: ViewContainerRef; attachPortal() { const portal = new ComponentPortal(PortalContentComponent); this.portalOutlet.attach(portal); } } @Component({ selector: 'portal-content', template: '<div>This is the portal content!</div>' }) export class PortalContentComponent {} ``` #### React 中的 Portal 示例 在 React 中,可以使用 `ReactDOM.createPortal()` 来实现 Portal。以下是一个简单的示例代码: ```jsx import React from 'react'; import ReactDOM from 'react-dom'; const Portal = ({ children }) => { const portalRoot = document.getElementById('portal-root'); return ReactDOM.createPortal(children, portalRoot); }; function App() { return ( <div> <h1>Main Content</h1> <Portal> <div style={{ position: 'fixed', top: '0', left: '0', zIndex: '999' }}> This is the portal content! </div> </Portal> </div> ); } export default App; ``` 在这个示例中,`Portal` 组件会将传入的 `children` 渲染到 `id` 为 `portal-root` 的 DOM 节点中,从而实现脱离当前组件层级的渲染。 ### 三级标题:总结 Portal 是一种非常实用的技术,尤其在需要将 UI 元素渲染到当前组件层级之外的场景中。无论是 Angular 还是 React,都提供了相应的实现方式来简化 Portal 的使用。通过合理地运用 Portal,可以有效解决样式污染、布局限制等问题,提升用户体验和开发效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值