Configurable Routing
在單頁應用程式中,您可以通過顯示應用程式的不同視圖來控制使用者看到的内容。 Spartacus 使用 Angular Router 來處理從一個視圖到另一個視圖的導航。 路由器通過将每個 URL 視為呈現特定視圖的指令來完成此操作。
Spartacus 允許您自定義這些 URL,讓您更好地控制 SEO 和店面可用性。 Spartacus 包含用于通路不同視圖的預設路由,無需任何配置即可使用。 您還可以選擇在 Spartacus 中自定義您想要的任何路線。
Adding and Customizing Routes
Spartacus 包含用于通路店面應用程式中不同視圖的預設路由,但您也可以在 Spartacus 中添加或自定義所需的任何路由。
Page Types and Page Labels
SAP Commerce Cloud 中的 CMS 包括以下特殊頁面類型:産品、類别和目錄。 還有一個通用的内容頁面類型,用于所有其他類型的頁面,例如登入、訂單曆史和常見問題頁面。
是以總共是四大類型。
Spartacus 預設定義了以下 Angular Routes:
包含 :productCode 參數的路由用于産品頁面
包含 :categoryCode 參數或 :brandCode 參數的路由用于類别頁面
包含 “**” 通配符的路由适用于内容頁面(換句話說,通配符适用于所有不是産品或類别頁面的頁面)
内容頁面在 CMS 中有一個可配置的 URL,稱為頁面标簽。換句話說,我們可以在 CMS 中通過 page label 來配置内容頁面的 URL.
但是,産品、類别和品牌頁面的 URL 隻能在 Spartacus 中配置。
Adding a Content Page Route
要添加新路由,您隻需在 CMS 中添加一個新的内容頁面,并為其指定一個以斜杠開頭的頁面标簽,例如 /contact-us。 Spartacus 通配符路由 (**) 無需任何配置即可比對。
Customizing a Product or Category Page Route
您隻能在 Spartacus 中配置 Product 和 Category 頁面路由。
産品頁面路由必須包含 :productCode 參數來辨別産品。 類别頁面路由必須包含 :categoryCode 或 :brandCode 參數來辨別類别。
對于 SEO,您可能希望在路線中包含更多參數。 以下是将産品名稱添加到産品頁面路由的示例 ConfigModule:
routing: {
routes: {
product: { paths: ['product/:name/:productCode'] }
}
}
1
2
3
4
5
Adding a Content Page with Dynamic Parameter
Angular 路由可以包含由 Angular 元件的邏輯使用的動态路由參數。 盡管 SAP Commerce CMS 不支援帶有動态參數的頁面标簽,但您可以在 Spartacus 中為内容頁面設定動态參數。
在 app.module.ts 中,您使用 path 屬性定義自定義 Angular Route 的 URL 路徑,并使用 data 屬性顯式配置設定 CMS 頁面标簽。 下面是一個例子:
import { PageLayoutComponent, CmsPageGuard } from `@spartacus/storefront`;
/* ... */
imports: [
RouterModule.forChild([
{
// path with a dynamic parameter:
path: 'order/:orderCode',
// page label without a parameter, starting with slash:
data: { pageLabel: '/order' },
// the following are needed to display slots and components from the CMS:
component: PageLayoutComponent,
canActivate: [CmsPageGuard]
}
]),
]
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Route Configuration
Spartacus 在 default-routing-config.ts 中包含預定義的路由配置,允許您運作店面應用程式而根本不需要配置任何路由。 但是,Spartacus 中的所有路由都可以通過使用包含路由屬性的對象導入 ConfigModule.withConfig() 來配置,并且預定義配置的每個部分也可以使用 ConfigModule.withConfig() 進行擴充或覆寫。
以下是擴充預定義配置的示例:
ConfigModule.withConfig({
routing: {
routes: {
product: { paths: [':productCode/custom/product-path'] }
})
預定義的配置被擴充和覆寫按照如下規則實施:
開發人員提供的對象,擴充預定義的對象
開發人員提供的值,例如基元、數組和空值,會覆寫預定義的值
擴充預定義配置時,必須始終使用預定義配置中的路由參數,例如 product/:productCode 路徑中的 :productCode 參數。 如果省略路由參數,店面的元件可能會損壞。 以下是一個錯誤的做法:
product: { paths: ['product/:productName'] } // overwritten without :productCode
Working with Angular Routes
要使路由可配置,它們需要在 data.cxRoute 屬性和配置中的路由鍵中命名相同。也就是說,多處的 route 名稱必須保持一緻。
以下示例顯示了 data.cxRoute 屬性,該屬性将路由名稱定義為“product”:
const routes: Routes = [
{
data: {
cxRoute: 'product' // the name of the route
},
path: null, // it will be replaced by the path from config
component: ProductPageComponent
/* ... */
];
Configurable Router Links
配置路由時,必須相應地配置到這些路由的連結。 可以使用 cxUrl 管道在 HTML 模闆中自動生成已配置的路由器連結。 這允許您将路由的名稱和 params 對象轉換為配置的路徑。
要使用 cxUrl 管道,您需要将 UrlModule 導入到使用可配置路由器連結的每個子產品中。
預設情況下,輸出路徑數組是絕對的,并包含一個前導正斜杠“/”。 但是,當輸入以不是具有 cxRoute 屬性的對象的元素(例如字元串“./”或“…/”或 {)開頭時,輸出路徑不包含前導正斜杠“/” not_cxRoute_property: … }。 另請注意,無法從路由名稱和參數解析的路由将傳回根 URL [’/’]。
Router Links
您可以按如下方式轉換路由名稱和 params 對象:
{ cxRoute: } | cxUrl
下面是一個例子:
上面例子對應的 route 配置:
cart: { paths: ['custom/cart-path'] }
上面例子轉換的結果:
routerLink 是一個指令:當應用于模闆中的元素時,使該元素成為開始導航到某個路由的連結。導航會在頁面上的 router-outlet 位置上打開一個或多個路由元件。
Programmatic API
Navigation to the Generated Path
使用 { cxRoute: } 調用的 RoutingService.go 方法導航到生成的路徑,類似于 HTML 模闆中帶有 cxUrl 管道的 routerLink。
下面是一個配置:
product: { paths: ['p/:productCode'] }
代碼調用:
routingService.go({ cxRoute: 'product', params: { productCode: 1234 } });
Disabling Standard Routes
Spartacus 中的标準 Angular 路由,例如産品詳細資訊頁面的路由,可以通過配置禁用。 這可能很有用,例如,當您想要提供自定義路由時。 禁用路由時,路徑配置僅用于生成路由器連結。
下列代碼能禁掉 product 明細頁面的路由:
routing: {
product: {
disabled: true,
paths: /* ... */
}
}
路由别名
可以在路徑數組中配置多個路由别名。 然後 Spartacus 使用第一個配置的别名生成路由器連結,該别名可以滿足帶有 params 對象的路徑數組的參數。 是以,您需要将别名從需要最具體參數的别名到具有最少參數的别名排序。
在以下示例中,配置具有正确順序的路由别名:
product: {
paths: [
':campaignName/p/:productCode', /* this will be used when the `campaignName` parameter is provided */
'p/:productCode' /* this will be used otherwise */
]
}