通过无外设的 Oracle Content Management 在愤怒中构建博客
简介
Angular 是一个用于构建移动和桌面 Web 应用的平台。但如果需要内容管理系统 (CMS) 来满足您的所有内容,会发生什么情况?幸运的是,Oracle Content Management 拥有丰富的无外界 CMS 功能,可满足您的内容管理和治理需求。
在本教程中,我们将利用 Oracle Content Management 作为无标题 CMS 及其软件开发工具包 (SDK) 来在 Angular 中构建一个简单的博客,以便在 JavaScript 中提供内容。GitHub 上提供了此 Angular 示例。
本教程包含三个步骤:
先决条件
在继续本教程之前,建议您先阅读以下信息:
要遵循本教程,您将需要:
- Oracle Content Management 订阅
- 具有内容管理员角色的 Oracle Content Management 账户
- 节点版本为 10 或更高版本的 Windows 或 Mac 计算机
正在构建的内容
我们的博客将包含三页网站,让访问者能够浏览有组织的博客文章。第一页(主页)将包含品牌(公司名称和徽标),一些链接和博客主题列表。
要了解我们正在构建什么,本教程的最终状态就是一个消耗 Oracle Content Management 内容的基本 Angular 博客:
https://headless.mycontentdemo.com/samples/oce-angular-blog-sample
主页 将在本教程结束时显示如下内容:

第二页( 主题页 )显示属于该主题的每个博客文章的预览。以下是各个主题页面的外观:

最后, 文章页 呈现最终博客文章,包括有关博客作者的信息。以下是各个文章页面的外观:

要继续,您需要具有对 Oracle Content Management 的有效订阅,并使用内容管理员角色登录。
任务 1:准备 Oracle Content Management
如果您还没有 Oracle Content Management 实例,请参阅 快速入门 来了解如何注册 Oracle Cloud、预配 Oracle Content Management 实例以及将 Oracle Content Management 配置为无外设 CMS。
对于本教程,您将需要通过两种方式之一来创建内容模型。可以使用 可下载资产包 来填充空库中的内容类型和关联内容,也可以创建自己的内容模型和内容。
要准备 Oracle Content Management,请执行以下操作:
- 创建渠道和资产信息库 。
- 使用以下两种方法之一 创建内容模型 :
- 方法 1: 导入 Oracle Content Management 样品资产包
- 方法 2: 创建您自己的内容模型
创建渠道和资产信息库
您首先需要在 Oracle Content Management 中创建渠道和资产存储库,以便可以发布内容。
要在 Oracle Content Management 中创建渠道和资产存储库,请执行以下操作:
以管理员身份登录到 Oracle Content Management Web 界面。
在左侧导航菜单中选择 内容 ,然后从页面标题的选择列表中选择 发布渠道 。

在右上角,单击 创建 以创建新通道。为本教程的目的命名通道 ‘ OCEGettingStartedChannel ’,并将访问保持为公共。单击 保存 以创建通道。

在左侧导航菜单中选择 内容 ,然后从页面标题的选择列表中选择 资料档案库 。

在右上角,单击 创建 以创建新的资产资料档案库。为本教程的目的,将资产存储库命名为 'OCEGettingStartedRepository'。

在 发布渠道 字段中,选择 OCEGettingStartedChannel 通道以指示 Oracle Content Management OCEGettingStartedRepository 资料档案库中的内容可以发布到 OCEGettingStartedChannel 通道。完成后单击 保存 。

创建内容模型
下一步是创建内容模型。您可以使用以下两种方法之一:
- 方法 1: 导入 Oracle Content Management 样品资产包
- 方法 2: 创建您自己的内容模型
导入 Oracle Content Management 样品资产包
您可以下载预配置的 Oracle Content Management 样例资产包,其中包含本教程的所有必需内容类型和资产。如果您愿意,也可以 创建自己的内容模型 ,而不是下载示例资产包。
您可以从 Oracle Content Management Samples Asset Pack 上载我们在本教程中使用的内容的副本。这允许您试验内容类型并修改内容。如果要导入 Oracle Content Management 样品资产包,您可以下载资产包档案 OCESamplesAssetPack.zip,然后将其提取到您选择的目录:
从 Oracle Content Management 下载 页下载 Oracle Content Management 样品资产包 (OCESamplesAssetPack.zip)。将下载的 zip 文件解压缩到您计算机上的某个位置。提取之后,此位置将包含一个名为 OCEGettingStarted_data.zip 的文件。
以管理员身份登录到 Oracle Content Management Web 界面。
在左侧导航菜单中选择 内容 ,然后从页面标题的选择列表中选择 资料档案库 。现在选择 OCEGettingStartedRepository,然后单击顶部操作栏中的 导入内容 按钮。

将 OCEGettingStarted_data.zip 从本地计算机上载到 Documents 文件夹。

上载后,选择 OCEGettingStarted_data.zip,然后单击 确定 将内容导入您的资产存储库。

成功导入内容后,导航到 资产 页并打开 OCEGettingStartedRepository 系统信息库。您将看到所有相关的图像和内容项现在已添加到资产存储库中。

单击左上角的 全选 ,然后单击 发布 将所有导入资产添加到您之前创建的发布渠道 OCEGettingStartedChannel。

在发布之前,您需要验证所有资产。首先将 OCEGettingStartedChannel 添加为所选通道,然后单击 验证 按钮。

在验证资产后,您可以通过单击右上角的 发布 按钮将所有资产发布到选定的渠道。

完成此操作后,您可以在 资产 页面上看到所有资产都已发布。(您可以按资产名称上方的图标。)

导入 Oracle Content Management 样品资产包后,您可以开始在 Angular 中构建博客。
创建您自己的内容模型
您也可以创建自己的内容模型,而不是 导入 Oracle Content Management 样品资产包 。
对于本教程,我们使用名为“OCEGettingStartedHomePage”的内容类型来构建博客的主页。此主页包含品牌(公司名称和徽标)、某些链接 URL 以及应包含在页面上的博客主题列表。

要创建内容模型的内容类型,请执行以下操作:
- 以管理员身份登录到 Oracle Content Management Web 界面。
- 在左侧导航菜单中选择 内容 ,然后从页面标题的选择列表中选择 资产类型 。
- 单击右上角的 创建 。
- 选择创建内容类型(而非数字资产类型)。对所有必需的内容类型重复此操作。

我们将创建四个内容类型,每个类型都有自己的字段集:
- OCEGettingStartedHomePage
- OCEGettingStartedTopic
- OCEGettingStartedAuthor
- OCEGettingStartedArticle
第一个内容类型 OCEGettingStartedHomePage 应具有以下字段:
| 显示名称 | 字段类型 | 必需 | 计算机名 |
|---|---|---|---|
| 公司名称 | 单值文本字段 | X | company_name |
| 公司标识 | 单值文本字段 | X | company_logo |
| 主题 | 多值参考字段 | X | 主题 |
| 联系人 URL | 单值文本字段 | X | contact_url |
| 关于 URL | 单值文本字段 | X | about_url |
OCEGettingStartedHomePage 内容类型定义应如下所示:

第二种内容类型 OCEGettingStartedTopic 应具有以下字段:
| 显示名称 | 字段类型 | 必需 | 计算机名 |
|---|---|---|---|
| 缩略图 | 单值图像字段 | X | 缩略图 |
OCEGettingStartedTopic 内容类型应如下所示:

第三种内容类型 OCEGettingStartedAuthor 应具有以下字段:
| 显示名称 | 字段类型 | 必需 | 计算机名 |
|---|---|---|---|
| 头像 | 单值图像字段 | X | 头像 |
OCEGettingStartedAuthor 内容类型应如下所示:

第四种和最终内容类型 OCEGettingStartedArticle 应具有以下字段:
| 显示名称 | 字段类型 | 必需 | 计算机名 |
|---|---|---|---|
| 发布日期 | 单值日期字段 | X | published_name |
| 作者 | 单值参考字段 | X | 作者 |
| 图像 | 单值图像字段 | X | 图像 |
| 图像标题 | 单值文本字段 | X | image_caption |
| 文章内容 | 单值大文本字段 | X | article_content |
| 主题 | 单值参考字段 | X | 主题 |
OCEGettingStartedArticle 内容类型应如下所示:

创建内容类型后,可以将这些内容类型添加到先前创建的 OCEGettingStartedRepository 系统信息库中:
- 以管理员身份登录到 Oracle Content Management Web 界面。
- 导航到 OCEGettingStartedRepository。
- 编辑资料档案库,并在 资产类型 下指定所有四个新创建的内容类型。
- 单击 保存 按钮以保存更改。

将内容类型添加到资料档案库后,可以在 资产 页上打开 OCEGettingStartedRepository 资料档案库,然后开始为所有内容类型创建内容项。

任务 2:以愤怒方式构建博客
要在 Angular 应用程序中使用 Oracle Content Management 内容,我们可以使用 Angular 博客示例,该示例可用作 GitHub 上的开源资料档案库。
注意: 请记住,使用 Angular 示例是可选的,在本教程中使用它可帮助您快速入门。您还可以构建自己的 Angular 应用程序,例如使用 Angular CLI 通过添加服务器端呈现支持来通过 Angular CLI 构建一个基架。
以英语构建博客:
克隆示例资料档案库和安装相关性
Angular 博客示例作为 GitHub 上的开源系统信息库提供。
您首先需要将示例从 GitHub 克隆到本地计算机,并将目录更改为系统信息库根:
git clone https://github.com/oracle/oce-angular-blog-sample.git
cd oce-angular-blog-sample
现在,您已经有了代码库,您需要下载应用程序的依赖项。从根目录运行以下命令:
npm install
配置中间应用程序
在此愤怒博客示例中,您需要配置几条信息,以便您的 Oracle Content Management Content SDK(以及任何其他请求)可以使用正确的渠道标记定位正确的实例 URL 和 API 版本。在 src/scripts/server-config-utils.js 中使用这些值来实例化新的传送客户机。
此应用程序使用 Webpack 在捆绑客户机和服务器应用程序时读取的 .env 文件。使用 webpack.DefinePlugin,从 .env 文件读取的任何值都可以提供给应用程序中的任何位置。
在文本编辑器中打开 .env 文件。您将看到以下信息:
# The connection details for the Oracle Content Management server to be used for this application
SERVER_URL=https://samples.mycontentdemo.com
API_VERSION=v1.1
CHANNEL_TOKEN=47c9fb78774d4485bc7090bf7b955632
更改每个键 - 值对以反映您的实例 URL、要定位的 API 版本以及与发布渠道关联的通道标记。此教程的渠道为 OCEGettingStartedChannel。
使用 Oracle Content Management Content SDK
Oracle Content Management 提供了 SDK 来帮助发现和使用应用程序中的内容。SDK 作为 NPM 模块 发布,项目托管在 GitHub 上。
在此处 了解有关 SDK 的更多信息。
SDK 已在 package.json 文件中注册为此项目的运行时相关性。
使用内容 SDK 提取内容
我们现在可以利用 Content SDK 提取内容,以便可以在 Angular 应用中呈现。
Content SDK 使用 DeliveryClient 对象指定端点。可以使用该客户端对象进行所有请求。
src/scripts 文件夹包含使用 Content SDK 从 Oracle Content Management 获取数据的代码。
src/scripts/server-config-utils.js 文件导入 Content SDK,然后使用 .env 中指定的配置创建传送客户机。
以下命令导入 SDK:
import { createDeliveryClient, createPreviewClient } from '@oracle/content-management-sdk';以下命令创建传送客户机:
return createDeliveryClient(serverconfig);对于呈现图像,service.js 提供了一种辅助方法来检索从资产重现中构建的资产的资源集。
function getSourceSet(asset) {
const urls = {};
urls.srcset = '';
urls.jpgSrcset = '';
if (asset.fields && asset.fields.renditions) {
asset.fields.renditions.forEach((rendition) => {
addRendition(urls, rendition, 'jpg');
addRendition(urls, rendition, 'webp');
});
}
// add the native rendition to the srcset as well
urls.srcset += `${asset.fields.native.links[0].href} ${asset.fields.metadata.width}w`;
urls.native = asset.fields.native.links[0].href;
urls.width = asset.fields.metadata.width;
urls.height = asset.fields.metadata.height;
return urls;
}src/scripts/services.js 文件包含用于获取应用程序数据的所有代码。应用程序中的每个页面组件都有一个主要功能,用于获取该页面的所有数据。
主页数据
主页需要调用多个数据才能获取其所有数据:
- 首先,我们在 .env 中指定的通道中查询项目。
- 对于每个主题项目,我们会提取其详细信息。
打开 src/scripts/services.js 并找到 getTopicsListPageData() 函数,此函数将获取主页的所有数据。
export function getTopicsListPageData() {
const client = getClient();
return fetchHomePage(client)
.then((data) => (
getRenditionURLs(client, data.logoID)
.then((renditionUrls) => {
data.companyThumbnailRenditionUrls = renditionUrls;
return data;
})
));
}由 getTopicsListPageData() 函数调用的 fetchHomePage() 函数获取通道中的所有项。这将获取徽标 ID、公司名称、关于和联系 URL 以及主题列表。
function fetchHomePage(client) {
return client.queryItems({
q: '(type eq "OCEGettingStartedHomePage" AND name eq "HomePage")',
}).then((data) => {
const logoID = data.items[0].fields.company_logo.id;
const title = data.items[0].fields.company_name;
const aboutUrl = data.items[0].fields.about_url;
const contactUrl = data.items[0].fields.contact_url;
const { topics } = data.items[0].fields;
const promises = [];
topics.forEach((origTopic) => {
// add a promise to the total list of promises to get the full topic details
promises.push(
fetchTopic(client, origTopic.id)
.then((topic) => topic),
);
});
// execute all the promises returning a single dimension array of all
// of the topics and the other home page data
return Promise.all(promises)
.then((allTopics) => (
{
logoID,
companyTitle: title,
aboutUrl,
contactUrl,
topics: flattenArray(allTopics),
}
)).catch((error) => logError('Fetching topics failed', error));
}).catch((error) => logError('Fetching home page data failed', error));
}然后,为每个主题 ID 调用 fetchTopic() 函数以获取完整主题详细信息。
function fetchTopic(client, topicId) {
return client.getItem({
id: topicId,
expand: 'fields.thumbnail',
}).then((topic) => {
topic.renditionUrls = getSourceSet(topic.fields.thumbnail);
return topic;
}).catch((error) => logError('Fetching topic failed', error));
}getTopicsListPageData() 还调用 getRenditionURLs() 以获取要呈现的图像的 URL。
function getRenditionURLs(client, identifier) {
return client.getItem({
id: identifier,
expand: 'fields.renditions',
}).then((asset) => getSourceSet(asset))
.catch((error) => logError('Fetching Rendition URLs failed', error));
}主题页数据
主题页接收主题 ID,需要多次数据调用才能获取其所有数据:
- 获取指定主题的所有文章。
- 对于每篇文章,获取其重现 URL。
打开 src/scripts/services.js 并查找 fetchTopicArticles(topicId) 函数,用于获取主题页面的所有数据。
export function fetchTopicArticles(topicId) {
const client = getClient();
return client.queryItems({
q: `(type eq "OCEGettingStartedArticle" AND fields.topic eq "${topicId}")`,
orderBy: 'fields.published_date:desc',
}).then((data) => {
const promises = [];
const articles = data.items;
articles.forEach((article) => {
// add a promise to the total list of promises to get the article url
promises.push(
getRenditionURLs(client, article.fields.image.id)
.then((renditionUrls) => {
article.renditionUrls = renditionUrls;
// Note: the spread operator is used here so that we return a top level
// object, rather than a value which contains the object
// i.e we return
// {
// field1: 'value', field2 : "value", etc
// },
// rather than
// {
// name: {
// field1: 'value', field2 : "value", etc
// }
// }
return {
...article,
};
}),
);
});
// execute all the promises and return all the data
// execute all the promises and return all the data
return Promise.all(promises)
.then((allArticles) => ({
topicId,
articles: flattenArray(allArticles),
}));
}).catch((error) => logError('Fetching topic articles failed', error));
}fetchTopicArticles() 方法还使用之前看到的 getRenditionURLs() 来获取文章的图像。
文章页数据
文章页面收到文章 ID,需要多次数据调用才能获取其所有数据:
- 获取指定文章的文章详细信息。对于每篇文章,获取其重现 URL。
- 获取作者头像的重现 URL。
打开 src/scripts/services.js 并查找 fetchArticleDetails(articleId) 函数,从而获取文章页的数据。
export function fetchArticleDetails(articleId) {
const client = getClient();
return client.getItem({
id: articleId,
expand: 'fields.author,fields.image',
}).then((article) => {
const title = article.fields.author.name;
const date = article.fields.published_date;
const content = article.fields.article_content;
const imageCaption = article.fields.image_caption;
const { name } = article;
const renditionUrls = getSourceSet(article.fields.image);
const avatarID = article.fields.author.fields.avatar.id;
// Get the author's avatar image
return getRenditionURLs(client, avatarID)
.then((authorRenditionUrls) => (
// return an object with just the data needed
{
id: articleId,
name,
title,
date,
content,
imageCaption,
renditionUrls,
authorRenditionUrls,
}
));
}).catch((error) => logError('Fetching article details failed', error));
}fetchArticleDetails() 方法还使用前面的 getRenditionURLs() 获取头像图像。
现在,我们有了数据查询,可以在 Angular components 中呈现响应。
客户端与服务器端呈现
使用客户端呈现 (CSR),客户端负责使用 JavaScript 构建和呈现 Web 页的内容。使用服务器端呈现 (Server-sideendering, SSH) 构建在服务器上,并向客户机返回完整 Web 页。
在客户端呈现中从服务器请求 Web 页时,返回的 HTML 文档包含框架 HTML,并且没有实际内容。它包含对 JavaScript 包的引用,客户机随后从服务器请求了该包。收到此包后,客户端执行 JavaScript 并填充 Web 页。在客户端完成 JavaScript 的执行之前,所有用户看到的都是空白网页。客户端呈现的应用程序的一个缺点是,当某些 Web 爬取器为站点编制索引时,没有实际的内容可索引。
使用服务器端呈现 (Server-sideendering, SSH) 构建在服务器上,并向客户机返回完整 Web 页。其优点是,Web 爬取器可以在网页上对整个内容进行索引。
边缘服务器端呈现
Angular 博客应用的流程如下:
- 客户机针对给定路由向服务器发出请求。
- Express 服务器收到请求。
- Express 服务器将所有页面的客户端请求传递到 Angular Univeral 的 Express 引擎
- Angular Univeral 的 Express 引擎采用模板 HTML 文件并使用以下方法对其进行填充
- 给定路由的标记
- 路由数据已串行化输出
- 对任何样式表的引用
- 对要在客户端上运行的 JavaScript 包的引用
- Express 服务器将 Angular Univeral 的 Express Engine 创建的 HTML 文档返回给客户端
- 客户机收到 HTML 并呈现出来。用户将看到完全格式的网页。
- 客户机从服务器请求任何 JavaScript 包。接收后,客户端在包中运行 JavaScript。
- 它“冻结” HTML,在任何客户端 JavaScript 中添加,例如事件监听程序。
- Angular 自动从页面获取序列化数据并将其注入到可供组件使用的 JavaScript 代码中
- 如果 HTML 文档包含样式表,客户端会请求样式表。
整型 CLI 支持将服务器端呈现支持添加到现有 Angular 应用程序。有关更多详细信息,请参见 https://angular.io/guide/universal。
服务器端 Express 服务器
服务器应用程序使用 Express 服务器接收请求并转发到 Angular Univeral 的 Express 引擎。
Express 服务器文件位于 server.js。添加服务器端呈现支持时,此文件由 Angular CLI 创建。
角形组件
愤怒组件在 TypeScript 中编写并定义用于定义视图的模板。这些模板包含普通 HTML、Angular 指令和绑定标记,这使得 Angular 在呈现 HTML 之前对其进行调整。
博客应用程序将每页分成几个较小的组件。
接下来的几节概述了 Angular 如何在我们每个组件中呈现应用:
- 应用程序模块
- 服务器端呈现的根模块
- 主题列表数据解析程序
- 文章列表数据解析程序
- 文章详细信息数据解析程序
- 应用程序组件
- TopicsList 组件
- TopicListItem 组件
- ArticlesList 组件
- ArticleDetails 组件
应用程序模块
位于 src/app/app.module.ts 中的应用程序模块。它使用 应用程序组件 引导应用程序。
此文件定义应用程序的不同路由。在我们的网站上,我们要提供三条路线:
- 主页,由主题列表组成
- 主题页,其中显示所选主题的所有文章
- 文章页,显示所选文章
请注意,主题页和文章页都使用 Oracle Content Management 在 URL 中提供的参数。
主页、主题页和文章页路由定义解析器,用于在创建路由组件之前获取路由所需的所有数据。
const appRoutes: Routes = [
// home page - list of Topics
{
path: 'topics',
component: TopicsListComponent,
resolve: { routeData: TopicsListDataResolver }
},
// list of articles for a specific Topic
{
path: 'articles/:topicId',
component: ArticlesListComponent,
resolve: { routeData: ArticlesListDataResolver }
},
// details for a specific Article
{
path: 'article/:articleId',
component: ArticleDetailsComponent,
resolve: { routeData: ArticleDetailsDataResolver }
},
// no path specified, go to home
{
path: '', redirectTo: '/topics', pathMatch: 'full'
},
// path not found
{ path: '**', component: PageNotFoundComponent },
];在客户端呈现应用程序时,此应用程序模块是入口点。
服务器端呈现的根模块
在服务器上呈现应用程序时,此 Angular 应用程序的主要入口点是位于 src/app/app.server.module.ts 中的应用程序服务器模块。
此模块将导入位于 src/app/app.server.module.ts 中的应用程序模块以及 Angular 的 ServerModule。服务器端应用程序引导与客户端相同的应用程序组件,并使用所有相同的组件。
添加服务器端呈现支持时,Angular CLI 将创建服务器模块文件。
主题列表数据解析程序
主题列出了位于 src/resolver/topics-list-data.resolver.ts 中的数据解析器,用于处理在主页中呈现的数据。
当客户机进行水合时,可从 transferState 获取此数据,该 transferState 在服务器端呈现期间填充,并串行化到返回到客户机的 HTML 文档中。
在出现客户端导航时,在服务器端呈现或客户端呈现期间,transferState 不包含数据。通过从 src/scripts/services.js 调用 getTopicsListPageData() 方法,可使用 Content SDK 从 Oracle Content Management 服务器获取数据。
文章列表数据解析程序
文章会列出位于 src/resolver/articles-list-data.resolver.ts 中的数据解析器,处理在主题页中呈现的数据。
当客户机进行水合时,可从 transferState 获取此数据,该 transferState 在服务器端呈现期间填充,并串行化到返回到客户机的 HTML 文档中。
在出现客户端导航时,在服务器端呈现或客户端呈现期间,transferState 不包含数据。通过从 src/scripts/services.js 调用 fetchTopicArticles() 方法,可使用 Content SDK 从 Oracle Content Management 服务器获取数据。
文章详细信息数据解析程序
文章详细介绍位于 src/resolver/article-details-data.resolver.ts 中的数据解析器,用于获取要在文章页中呈现的数据。
当客户机进行水合时,可从 transferState 获取此数据,该 transferState 在服务器端呈现期间填充,并串行化到返回到客户机的 HTML 文档中。
在出现客户端导航时,在服务器端呈现或客户端呈现期间,transferState 不包含数据。通过从 src/scripts/services.js 调用 fetchArticleDetails() 方法,可使用 Content SDK 从 Oracle Content Management 服务器获取数据。
应用程序组件
应用程序组件位于 src/app/app.component.ts 中,用于定义根视图。
此组件包含路由器链路标记。Angular 将根据当前路由在这些标记内外交换组件。
TopicsList 组件
主页由单个主题组成的列表组成。它由位于 src/app/topics-list/topics-list.component 的 TopicsList 组件呈现。
在 ngOnInit 中,组件从活动路由获取数据,该路由由主题列表数据解析器填充。
ngOnInit() {
const data = this.route.snapshot.data.routeData;
. . .
}当组件呈现时,它将从成员变量中获取所有数据。
TopicsList 组件的标记位于 src/app/topics-list/topics-list.component.html。
TopicListItem 组件
TopicsList 组件使用 TopicsListItem 组件在列表中显示各个主题。
它位于 src/app/topic-list-item.component.ts 处,接收其所有数据作为属性。它不会从服务器获取任何其他数据。
TopicsListItem 组件的标记位于 src/app/topic-list-item.component.html。
ArticlesList 组件
“主题”页显示主题中其 ID 传递到 URL 上的组件中的文章。它由位于 src/app/articles-list.component.ts 的 ArticlesList 组件呈现。
在 ngOnInit 中,您可以看到该组件从活动路由获取数据,该路由由文章列表数据解析器填充。
ngOnInit() {
const data = this.route.snapshot.data.routeData;
. . .
}当组件呈现时,它将从成员变量中获取所有数据。
ArticlesList 组件的标记位于 src/app/articles-list.component.html。
ArticleListItem 组件
ArticlesList 组件使用 ArticleListItem 组件在列表中显示各个文章。
此组件位于 src/app/article-list-item.component.ts 处,接收其所有数据作为属性。它不会从服务器获取任何其他数据。
ArticleListItem 组件的标记位于 src/app/article-list-item.component.html。
ArticleDetails 组件
“文章”页显示在 URL 上传递其 ID 的文章的详细信息。它由位于 src/app/article-details.component.ts 的 ArticleDetails 组件呈现。
在 ngOnInit 中,您可以看到该组件从活动路由获取数据,该路由由文章列表数据解析器填充。
ngOnInit() {
// get the values from the routed URL
this.articleId = this.route.snapshot.params[PAGE_PARAM_TOPIC_ARTICLE_ID];
this.topicId = this.route.snapshot.queryParams[PAGE_PARAM_TOPIC_ID];
this.topicName = this.route.snapshot.queryParams[PAGE_PARAM_TOPIC_NAME];
const data = this.route.snapshot.data.routeData;
. . .
}当组件呈现时,它将从成员变量中获取所有数据。
ArticleDetails 组件的标记位于 src/app/article-details.component.html。
任务 3:准备应用程序进行部署
现在,我们已经构建了 Angular 博客站点,需要将其显示在本地开发服务器上,这样我们就能在应用上线之前调试任何问题并预览应用。
在两个步骤中准备应用程序以进行部署:
搭建本地开发服务器
可以通过运行以下命令在本地启动开发服务器。
npm run dev
然后,打开浏览器,访问 http://localhost:4200 以了解您的站点是否有效。
使用脚本在开发和生产过程中构建和运行应用程序
对于生产,构建脚本将用于构建客户机和服务器代码。
npm run build
此脚本首先运行客户机构建,然后运行服务器构建。启动服务器应用程序之前,需要在服务器计算机上部署已构建的 dist/server 和 dist/browser,请使用以下命令:
npm run start
结论
在本教程中,我们已在 Angular 中创建了一个博客网站,可访问 GitHub。此站点使用 Oracle Content Management 作为无标题 CMS。在使用博客网站教程的已发布内容渠道设置和配置 Oracle Content Management 之后,我们安装并运行了 Angular 站点以提取所需内容并构建站点。
有关 Angular 的更多信息,请访问 Angular 网站。
了解文档中重要的 Oracle Content Management 概念。
您可以在 Oracle 帮助中心的 Oracle Content Management 示例页上找到更多这样的示例。
通过无外设的 Oracle Content Management 在愤怒中构建博客
F49069-01
2021 年 12 月
Copyright © 2021, Oracle and/or its affiliates.
第一作者:Oracle Corporation