mirror of https://github.com/abpframework/abp.git
10 changed files with 277 additions and 2 deletions
@ -1,3 +1,84 @@ |
|||||
# Component Replacement |
## 替换组件 |
||||
|
|
||||
TODO... |
你可以将一些ABP的组件替换为你自己的自定义组件. |
||||
|
|
||||
|
您可以**替换**但**不能自定义**默认ABP组件的原因是禁用或更改该组件的一部分可能会导致问题. 所以我们把这些组件称为可替换组件. |
||||
|
|
||||
|
### 如何替换组件 |
||||
|
|
||||
|
创建一个你想要使用的新组件,添加到 `AppModule` 中的 `declarations` 和`entryComponents` 中. |
||||
|
|
||||
|
然后打开 `app.component.ts` 使用 `AddReplaceableComponent` 将你的组件替换ABP组件. 如下所示: |
||||
|
|
||||
|
```js |
||||
|
import { ..., AddReplaceableComponent } from '@abp/ng.core'; // imported AddReplaceableComponent action |
||||
|
import { eIdentityComponents } from '@abp/ng.identity'; // imported eIdentityComponents enum |
||||
|
import { Store } from '@ngxs/store'; // imported Store |
||||
|
//... |
||||
|
export class AppComponent { |
||||
|
constructor(..., private store: Store) {} // injected Store |
||||
|
|
||||
|
ngOnInit() { |
||||
|
this.store.dispatch( |
||||
|
new AddReplaceableComponent({ |
||||
|
component: YourNewRoleComponent, |
||||
|
key: eIdentityComponents.Roles, |
||||
|
}), |
||||
|
); |
||||
|
//... |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### 如何替换布局 |
||||
|
|
||||
|
每个ABP主题模块有3个布局,分别是`ApplicationLayoutComponent`, `AccountLayoutComponent`, `EmptyLayoutComponent`. 这些布局可以用相同的方式替换. |
||||
|
|
||||
|
> 一个布局组件模板应该包含 `<router-outlet></router-outlet>` 元素. |
||||
|
|
||||
|
下面的例子解释了如何更换 `ApplicationLayoutComponent`: |
||||
|
|
||||
|
运行以下命令在 `angular` 文件夹中生成布局: |
||||
|
|
||||
|
```bash |
||||
|
yarn ng generate component shared/my-application-layout --export --entryComponent |
||||
|
|
||||
|
# You don't need the --entryComponent option in Angular 9 |
||||
|
``` |
||||
|
|
||||
|
在你的布局模板(`my-layout.component.html`)中添加以下代码: |
||||
|
|
||||
|
```html |
||||
|
<router-outlet></router-outlet> |
||||
|
``` |
||||
|
|
||||
|
打开 `app.component.ts` 添加以下内容: |
||||
|
|
||||
|
```js |
||||
|
import { ..., AddReplaceableComponent } from '@abp/ng.core'; // imported AddReplaceableComponent |
||||
|
import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents enum for component keys |
||||
|
import { MyApplicationLayoutComponent } from './shared/my-application-layout/my-application-layout.component'; // imported MyApplicationLayoutComponent |
||||
|
import { Store } from '@ngxs/store'; // imported Store |
||||
|
//... |
||||
|
export class AppComponent { |
||||
|
constructor(..., private store: Store) {} // injected Store |
||||
|
|
||||
|
ngOnInit() { |
||||
|
// added below content |
||||
|
this.store.dispatch( |
||||
|
new AddReplaceableComponent({ |
||||
|
component: MyApplicationLayoutComponent, |
||||
|
key: eThemeBasicComponents.ApplicationLayout, |
||||
|
}), |
||||
|
); |
||||
|
|
||||
|
//... |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## 下一步是什么? |
||||
|
|
||||
|
- [自定义设置页面](./Custom-Setting-Page.md) |
||||
|
|||||
@ -0,0 +1,3 @@ |
|||||
|
## 配置状态 |
||||
|
|
||||
|
TODO... |
||||
@ -0,0 +1,3 @@ |
|||||
|
# 内容投影 |
||||
|
|
||||
|
TODO... |
||||
@ -0,0 +1,46 @@ |
|||||
|
# 自定义设置页面 |
||||
|
|
||||
|
不同的模块提供它们的设置选项卡. 你可以通过3个步骤在项目中自定义设置页面. |
||||
|
|
||||
|
1. 创建一个组件 |
||||
|
|
||||
|
```js |
||||
|
import { Select } from '@ngxs/store'; |
||||
|
import { Component } from '@angular/core'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'app-your-custom-settings', |
||||
|
template: ` |
||||
|
custom-settings works! |
||||
|
`, |
||||
|
}) |
||||
|
export class YourCustomSettingsComponent { |
||||
|
// Your component logic |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
2. 添加 `YourCustomSettingsComponent` 到 `AppModule` 中的 `declarations`和 `entryComponents` 数组中. |
||||
|
|
||||
|
3. 打开 `app.component.ts` 在 `ngOnInit` 添加以下内容: |
||||
|
|
||||
|
```js |
||||
|
import { addSettingTab } from '@abp/ng.theme.shared'; |
||||
|
// ... |
||||
|
|
||||
|
ngOnInit() { |
||||
|
addSettingTab({ |
||||
|
component: YourCustomSettingsComponent, |
||||
|
name: 'Type here the setting tab title (you can type a localization key, e.g: AbpAccount::Login', |
||||
|
order: 4, |
||||
|
requiredPolicy: 'type here a policy key' |
||||
|
}); |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
导航到 `/setting-management` 路由你会看到以下变化: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
## 下一步是什么? |
||||
|
|
||||
|
- [懒加载 Scripts 与 Styles](./Lazy-Load-Service.md) |
||||
@ -0,0 +1,3 @@ |
|||||
|
# Dom插入(Scripts与Styles) |
||||
|
|
||||
|
TODO... |
||||
@ -0,0 +1,3 @@ |
|||||
|
## HTTP请求 |
||||
|
|
||||
|
TODO... |
||||
@ -0,0 +1,3 @@ |
|||||
|
# 如何懒加载 Scripts 与 Styles |
||||
|
|
||||
|
TODO... |
||||
@ -0,0 +1,3 @@ |
|||||
|
## 服务代理 |
||||
|
|
||||
|
TODO... |
||||
@ -0,0 +1,98 @@ |
|||||
|
# 轻松实现TrackByFunction |
||||
|
|
||||
|
`TrackByService` 是一个实用服务,为Angular模板中最常见的需求之一: `TrackByFunction` 提供简单的实现. 在继续下面的内容之前,请参先阅 [Angular 文档](https://angular.io/guide/template-syntax#ngfor-with-trackby). |
||||
|
|
||||
|
## 入门 |
||||
|
|
||||
|
你不必在模块或组件级别提供 `TrackByService`,因为它已经在**根中提供了**. 你可以在组件中注入并开始使用它. 为了获得更好的类型支持,你可以将迭代项目的类型传递给它. |
||||
|
|
||||
|
```js |
||||
|
import { TrackByService } from '@abp/ng.core'; |
||||
|
|
||||
|
@Component({ |
||||
|
/* class metadata here */ |
||||
|
}) |
||||
|
class DemoComponent { |
||||
|
list: Item[]; |
||||
|
|
||||
|
constructor(public readonly track: TrackByService<Item>) {} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
> 注意到 `track` 是 `public` 并且 `readonly` 了吗? 因为我们将看到一些在组件模板中直接使用 `TrackByService` 实例的方法示例. 可以把它看做反模式,但它有自身的优势,尤其是在利用组件继承时. 你始终可以使用公共组件属性. |
||||
|
|
||||
|
**成员也被导出做为独立的函数.** 如果你不想注入 `TrackByService`, 你可以直接在类中导入并使用这些函数. |
||||
|
|
||||
|
## 用法 |
||||
|
|
||||
|
有两种方法可用. |
||||
|
|
||||
|
1. 你可以直接注入 `TrackByService` 到你的组件并且使用它的成员. |
||||
|
2. 你可以在直接在组件属性上使用导出的函数. |
||||
|
|
||||
|
### 如何通过一个键跟踪项 |
||||
|
|
||||
|
你可以使用 `by` 获取一个 `TrackByFunction` , 该函数根据它的一个键来跟踪迭代的对象. 你可以将迭代类型传递给它获得类型支持. |
||||
|
|
||||
|
```html |
||||
|
<!-- template of DemoComponent --> |
||||
|
|
||||
|
<div *ngFor="let item of list; trackBy: track.by('id')">{%{{{ item.name }}}%}</div> |
||||
|
``` |
||||
|
|
||||
|
`by` 作为一个独立函数导出,命名为 `trackBy`. |
||||
|
|
||||
|
```js |
||||
|
import { trackBy } from "@abp/ng.core"; |
||||
|
|
||||
|
@Component({ |
||||
|
template: ` |
||||
|
<div |
||||
|
*ngFor="let item of list; trackBy: trackById" |
||||
|
> |
||||
|
{%{{{ item.name }}}%} |
||||
|
</div> |
||||
|
`, |
||||
|
}) |
||||
|
class DemoComponent { |
||||
|
list: Item[]; |
||||
|
|
||||
|
trackById = trackBy<Item>('id'); |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### 如何通过深度嵌套的键进行跟踪 |
||||
|
|
||||
|
你可以使用 `byDeep` 获取一个 `TrackByFunction` , 它根据深度嵌套的键跟踪迭代对象. 你可以将迭代类型传递给它获得类型支持. |
||||
|
|
||||
|
|
||||
|
```html |
||||
|
<!-- template of DemoComponent --> |
||||
|
|
||||
|
<div |
||||
|
*ngFor="let item of list; trackBy: track.byDeep('tenant', 'account', 'id')" |
||||
|
> |
||||
|
{%{{{ item.tenant.name }}}%} |
||||
|
</div> |
||||
|
``` |
||||
|
|
||||
|
`byDeep` 作为一个独立函数导出,命名为 `trackByDeep`. |
||||
|
|
||||
|
```js |
||||
|
import { trackByDeep } from "@abp/ng.core"; |
||||
|
|
||||
|
@Component({ |
||||
|
template: ` |
||||
|
<div |
||||
|
*ngFor="let item of list; trackBy: trackByTenantAccountId" |
||||
|
> |
||||
|
{%{{{ item.name }}}%} |
||||
|
</div> |
||||
|
`, |
||||
|
}) |
||||
|
class DemoComponent { |
||||
|
list: Item[]; |
||||
|
|
||||
|
trackByTenantAccountId = trackByDeep<Item>('tenant', 'account', 'id'); |
||||
|
} |
||||
|
``` |
||||
Loading…
Reference in new issue