diff --git a/docs/en/Customizing-Application-Modules-Overriding-Services.md b/docs/en/Customizing-Application-Modules-Overriding-Services.md
index d58f0f8565..7f0c0502ea 100644
--- a/docs/en/Customizing-Application-Modules-Overriding-Services.md
+++ b/docs/en/Customizing-Application-Modules-Overriding-Services.md
@@ -60,6 +60,7 @@ In most cases, you will want to change one or a few methods of the current imple
````csharp
[Dependency(ReplaceServices = true)]
+[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService))]
public class MyIdentityUserAppService : IdentityUserAppService
{
//...
@@ -262,4 +263,4 @@ See [Overriding the User Interface](Customizing-Application-Modules-Overriding-U
## How to Find the Services?
-[Module documents](Modules/Index.md) includes the list of the major services they define. In addition, you can investigate [their source code](https://github.com/abpframework/abp/tree/dev/modules) to explore all the services.
\ No newline at end of file
+[Module documents](Modules/Index.md) includes the list of the major services they define. In addition, you can investigate [their source code](https://github.com/abpframework/abp/tree/dev/modules) to explore all the services.
diff --git a/docs/en/Nightly-Builds.md b/docs/en/Nightly-Builds.md
index e7ebe0f33b..1a66af32e1 100644
--- a/docs/en/Nightly-Builds.md
+++ b/docs/en/Nightly-Builds.md
@@ -24,3 +24,18 @@ Now, you can install preview / nightly packages to your project from Nuget Brows
3. Search a package. You will see prereleases of the package formatted as `(VERSION)-preview(DATE)` (like *v0.16.0-preview20190401* in this sample).
4. You can click to the `Install` button to add package to your project.
+## Install & Uninstall Preview NPM Packages
+
+The latest version of preview NPM packages can be installed by the running below command in the root folder of application:
+
+```bash
+abp switch-to-preview
+```
+
+If you're using the ABP Framework preview packages, you can switch back to stable version using this command:
+
+```bash
+abp switch-to-stable
+```
+
+See the [ABP CLI documentation](./CLI.md) for more information.
\ No newline at end of file
diff --git a/docs/en/Tutorials/Part-1.md b/docs/en/Tutorials/Part-1.md
index 20b64f3189..85f5c47bac 100644
--- a/docs/en/Tutorials/Part-1.md
+++ b/docs/en/Tutorials/Part-1.md
@@ -22,7 +22,7 @@ end
### About this tutorial:
-In this tutorial series, you will build an ABP Commercial application named `Acme.BookStore`. In this sample project, we will manage a list of books and authors. **{{DB_Text}}** will be used as the ORM provider. And on the front-end side {{UI_Value}} and JavaScript will be used.
+In this tutorial series, you will build an ABP application named `Acme.BookStore`. In this sample project, we will manage a list of books and authors. **{{DB_Text}}** will be used as the ORM provider. And on the front-end side {{UI_Value}} and JavaScript will be used.
The ASP.NET Core {{UI_Value}} tutorial series consists of 3 parts:
@@ -34,11 +34,11 @@ The ASP.NET Core {{UI_Value}} tutorial series consists of 3 parts:
### Creating the project
-Create a new project named `Acme.BookStore` where `Acme` is the company name and `BookStore` is the project name. You can check out [creating a new project](../Getting-Started-{{if UI == 'NG'}}Angular{{else}}AspNetCore-MVC{{end}}-Template#creating-a-new-project) document to see how you can create a new project. We will create the project with ABP CLI. But first of all, we need to login to the ABP Platform to create a commercial project.
+Create a new project named `Acme.BookStore` where `Acme` is the company name and `BookStore` is the project name. You can check out [creating a new project](../Getting-Started-{{if UI == 'NG'}}Angular{{else}}AspNetCore-MVC{{end}}-Template#creating-a-new-project) document to see how you can create a new project. We will create the project with ABP CLI. But first of all, we need to login to the ABP Platform.
#### Create the project
-By running the below command, it creates a new ABP Commercial project with the database provider `{{DB_Text}}` and UI option `MVC`. To see the other CLI options, check out [ABP CLI](https://docs.abp.io/en/abp/latest/CLI) document.
+By running the below command, it creates a new ABP project with the database provider `{{DB_Text}}` and UI option `MVC`. To see the other CLI options, check out [ABP CLI](https://docs.abp.io/en/abp/latest/CLI) document.
```bash
abp new Acme.BookStore --template app --database-provider {{DB}} --ui {{UI_Text}}
diff --git a/docs/en/UI/Angular/Dom-Insertion-Service.md b/docs/en/UI/Angular/Dom-Insertion-Service.md
index d5ea9fe3a2..489a7a4e1f 100644
--- a/docs/en/UI/Angular/Dom-Insertion-Service.md
+++ b/docs/en/UI/Angular/Dom-Insertion-Service.md
@@ -35,17 +35,19 @@ class DemoComponent {
constructor(private domInsertionService: DomInsertionService) {}
ngOnInit() {
- this.domInsertionService.insertContent(
+ const scriptElement = this.domInsertionService.insertContent(
CONTENT_STRATEGY.AppendScriptToBody('alert()')
);
}
}
```
-In the example above, `` element will place at the **end** of `
`.
+In the example above, `` element will place at the **end** of `` and `scriptElement` will be an `HTMLScriptElement`.
Please refer to [ContentStrategy](./Content-Strategy.md) to see all available content strategies and how you can build your own content strategy.
+> Important Note: `DomInsertionService` does not insert the same content twice. In order to add a content again, you first should remove the old content using `removeContent` method.
+
### How to Insert Styles
If you pass a `StyleContentStrategy` instance as the first parameter of `insertContent` method, the `DomInsertionService` will create a `` element will place at the **end** of ``.
+In the example above, `` element will place at the **end** of `` and `styleElement` will be an `HTMLStyleElement`.
Please refer to [ContentStrategy](./Content-Strategy.md) to see all available content strategies and how you can build your own content strategy.
+> Important Note: `DomInsertionService` does not insert the same content twice. In order to add a content again, you first should remove the old content using `removeContent` method.
+
+### How to Remove Inserted Scripts & Styles
+
+If you pass the inserted `HTMLScriptElement` or `HTMLStyleElement` element as the first parameter of `removeContent` method, the `DomInsertionService` will remove the given element.
+
+```js
+import { DomInsertionService, CONTENT_STRATEGY } from '@abp/ng.core';
+
+@Component({
+ /* class metadata here */
+})
+class DemoComponent {
+ private styleElement: HTMLStyleElement;
+
+ constructor(private domInsertionService: DomInsertionService) {}
+
+ ngOnInit() {
+ this.styleElement = this.domInsertionService.insertContent(
+ CONTENT_STRATEGY.AppendStyleToHead('body {margin: 0;}')
+ );
+ }
+
+ ngOnDestroy() {
+ this.domInsertionService.removeContent(this.styleElement);
+ }
+}
+```
+
+In the example above, `` element **will be removed** from `` when the component is destroyed.
+
## API
### insertContent
```js
-insertContent(contentStrategy: ContentStrategy): void
+insertContent(
+ contentStrategy: ContentStrategy,
+): T
```
- `contentStrategy` parameter is the primary focus here and is explained above.
+- returns `HTMLScriptElement` or `HTMLStyleElement` based on given strategy.
+
+### removeContent
+
+```js
+removeContent(element: HTMLScriptElement | HTMLStyleElement): void
+```
+- `element` parameter is the inserted `HTMLScriptElement` or `HTMLStyleElement` element, which was returned by `insertContent` method.
## What's Next?
diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/List-Groups.md b/docs/en/UI/AspNetCore/Tag-Helpers/List-Groups.md
index b1e6e7f499..08b942bd09 100644
--- a/docs/en/UI/AspNetCore/Tag-Helpers/List-Groups.md
+++ b/docs/en/UI/AspNetCore/Tag-Helpers/List-Groups.md
@@ -19,7 +19,7 @@ Basic usage:
## Demo
-See the [list groups demo page](https://bootstrap-taghelpers.abp.io/Components/ListGroups) to see it in action.
+See the [list groups demo page](https://bootstrap-taghelpers.abp.io/Components/ListGroup) to see it in action.
## Attributes
diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Progress-Bars.md b/docs/en/UI/AspNetCore/Tag-Helpers/Progress-Bars.md
index dc69f7e47e..1f723f80ae 100644
--- a/docs/en/UI/AspNetCore/Tag-Helpers/Progress-Bars.md
+++ b/docs/en/UI/AspNetCore/Tag-Helpers/Progress-Bars.md
@@ -26,7 +26,7 @@ Basic usage:
## Demo
-See the [progress bars demo page](https://bootstrap-taghelpers.abp.io/Components/Progress-Bars) to see it in action.
+See the [progress bars demo page](https://bootstrap-taghelpers.abp.io/Components/Progressbars) to see it in action.
## Attributes
@@ -67,4 +67,4 @@ A value indicates if the background style of the progress bar is stripped. Shoul
A value indicates if the stripped background style of the progress bar is animated. Should be one of the following values:
* `false` (default value)
-* `true`
\ No newline at end of file
+* `true`
diff --git a/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md b/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md
index 4b98f7cfb2..1ba35adf80 100644
--- a/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md
+++ b/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md
@@ -60,6 +60,7 @@ context.Services.Replace(
````csharp
[Dependency(ReplaceServices = true)]
+[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService))]
public class MyIdentityUserAppService : IdentityUserAppService
{
//...
@@ -262,4 +263,4 @@ ObjectExtensionManager.Instance
## 如何找到服务?
-[模块文档](Modules/Index.md) 包含了定义的主要服务列表. 另外 你也可以查看[源码](https://github.com/abpframework/abp/tree/dev/modules)找到所有的服务.
\ No newline at end of file
+[模块文档](Modules/Index.md) 包含了定义的主要服务列表. 另外 你也可以查看[源码](https://github.com/abpframework/abp/tree/dev/modules)找到所有的服务.
diff --git a/docs/zh-Hans/Nightly-Builds.md b/docs/zh-Hans/Nightly-Builds.md
index 3d34330ca3..84ea243b05 100644
--- a/docs/zh-Hans/Nightly-Builds.md
+++ b/docs/zh-Hans/Nightly-Builds.md
@@ -23,3 +23,19 @@
2. 将包源更改为`全部`.
3. 搜索nuget包. 你将看到包的预发布格式为`(VERSION)-preview(DATE)` (如本示例中的**v0.16.0-preview20190401**).
4. 你可以单击`安装`按钮将包添加到项目中.
+
+## 安装和卸载预览NPM包
+
+预览NPM包的最新版本可以通过在应用程序的根文件夹命令运行命令安装:
+
+```bash
+abp switch-to-preview
+```
+
+如果你正在使用ABP框架预览包,你可以使用此命令切换回稳定版本:
+
+```bash
+abp switch-to-stable
+```
+
+参阅 [ABP CLI 文档](./CLI.md) 了解更多信息.
\ No newline at end of file
diff --git a/docs/zh-Hans/UI/Angular/Component-Replacement.md b/docs/zh-Hans/UI/Angular/Component-Replacement.md
index d2369901dc..e98ce4331e 100644
--- a/docs/zh-Hans/UI/Angular/Component-Replacement.md
+++ b/docs/zh-Hans/UI/Angular/Component-Replacement.md
@@ -1,3 +1,84 @@
-# Component Replacement
+## 替换组件
-TODO...
\ No newline at end of file
+你可以将一些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`. 这些布局可以用相同的方式替换.
+
+> 一个布局组件模板应该包含 `` 元素.
+
+下面的例子解释了如何更换 `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
+
+```
+
+打开 `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)
diff --git a/docs/zh-Hans/UI/Angular/Config-State.md b/docs/zh-Hans/UI/Angular/Config-State.md
new file mode 100644
index 0000000000..a022129c83
--- /dev/null
+++ b/docs/zh-Hans/UI/Angular/Config-State.md
@@ -0,0 +1,3 @@
+## 配置状态
+
+TODO...
\ No newline at end of file
diff --git a/docs/zh-Hans/UI/Angular/Container-Strategy.md b/docs/zh-Hans/UI/Angular/Container-Strategy.md
new file mode 100644
index 0000000000..daf3be01db
--- /dev/null
+++ b/docs/zh-Hans/UI/Angular/Container-Strategy.md
@@ -0,0 +1,87 @@
+# ContainerStrategy
+
+`ContainerStrategy` 是 @abp/ng.core 包暴露出的抽象类. 有两种扩展容器扩展策略: `ClearContainerStrategy` 和 `InsertIntoContainerStrategy`. 它们实现了相同的方法和属性,这两种策略都可以帮助你定义容器的准备方式和内容的投影位置.
+
+## API
+
+`ClearContainerStrategy` 是一个扩展了 `ContainerStrategy` 的类. 它允许你**将内容投影之前清除容器**.
+
+### 构造函数
+
+```js
+constructor(
+ public containerRef: ViewContainerRef,
+ private index?: number, // works only in InsertIntoContainerStrategy
+)
+```
+
+- `containerRef` 是在投影内容时使用的 `ViewContainerRef`.
+
+### getIndex
+
+```js
+getIndex(): number
+```
+
+该方法返回被 `0` 和 `containerRef` `length` 限制的给定索引. 对于没有索引的策略,它返回`0`.
+
+### prepare
+
+```js
+prepare(): void
+```
+
+此方法在内容投影之前调用. 基于使用的容器策略,它要么清除容器,要么什么都不做(空操作).
+
+## ClearContainerStrategy
+
+`ClearContainerStrategy` 是一个扩展了 `ContainerStrategy` 的类. 它允许你**将内容投影之前清除容器**.
+
+## InsertIntoContainerStrategy
+
+`InsertIntoContainerStrategy` 是一个扩展了 `ContainerStrategy` 的类. 它允许你**将内容投影到容器中的特定节点索引上**.
+
+## 预定义的容器策略
+
+可以通过 `CONTAINER_STRATEGY` 常量访问预定义的容器策略.
+
+### Clear
+
+```js
+CONTAINER_STRATEGY.Clear(containerRef: ViewContainerRef)
+```
+
+在内容投影之前清除给定的容器.
+
+
+### Append
+
+```js
+CONTAINER_STRATEGY.Append(containerRef: ViewContainerRef)
+```
+
+将投影内容附加到容器中.
+
+
+### Prepend
+
+```js
+CONTAINER_STRATEGY.Prepend(containerRef: ViewContainerRef)
+```
+
+将投影的内容预先写入容器中.
+
+### Insert
+
+```js
+CONTAINER_STRATEGY.Insert(
+ containerRef: ViewContainerRef,
+ index: number,
+)
+```
+
+将投影内容按照给定的索引(在`0` 到 `containerRef`的长度之间)插入到容器中.
+
+## 另请参阅
+
+- [ProjectionStrategy](./Projection-Strategy.md)
diff --git a/docs/zh-Hans/UI/Angular/Content-Projection-Service.md b/docs/zh-Hans/UI/Angular/Content-Projection-Service.md
new file mode 100644
index 0000000000..72fa468a79
--- /dev/null
+++ b/docs/zh-Hans/UI/Angular/Content-Projection-Service.md
@@ -0,0 +1,77 @@
+# 内容投影
+
+你可以使用位于@abp/ng.core包中的 `ContentProjectionService` 简单明确的投影内容.
+
+## 入门
+
+你不必在模块或组件级别提供 `ContentProjectionService`,因为它已经在**根中提供了**. 你可以在组件中注入并开始使用它. 为了获得更好的类型支持,你可以将迭代项目的类型传递给它.
+
+```js
+import { ContentProjectionService } from '@abp/ng.core';
+
+@Component({
+ /* class metadata here */
+})
+class DemoComponent {
+ constructor(private contentProjectionService: ContentProjectionService) {}
+}
+```
+
+## 用法
+
+你可以使用 `ContentProjectionService` 的 `projectContent` 方法在你的项目中动态的渲染组件和模板.
+
+### 如何将组件投影到根级别
+
+如果将 `RootComponentProjectionStrategy` 做为 `projectContent` 方法的第一个参数,那么 `ContentProjectionService` 会解析投影组件并放在根级别,它还为组件传递上下文.
+
+```js
+const strategy = PROJECTION_STRATEGY.AppendComponentToBody(
+ SomeOverlayComponent,
+ { someOverlayProp: "SOME_VALUE" }
+);
+
+const componentRef = this.contentProjectionService.projectContent(strategy);
+```
+
+在上面的示例中, `SomeOverlayComponent` 组件放置在 `` 的**末尾**并返回 `ComponentRef`. 另外将应用给定的上下文,因此组件的 `someOverlayProp` 被设置为 `SOME_VALUE`.
+
+> 你应该总是返回 `ComponentRef` 实例,因为它是对投影组件的引用,在你需要时使用该引用销毁投影视图和组件实例.
+
+### 如何将组件和模板投影到容器中
+
+如果将 `ComponentProjectionStrategy` 或 `TemplateProjectionStrategy` 做为 `projectContent` 方法的第一个参数,并且传递 `ViewContainerRef` 做为策略的第二个参数传递. 那么 `ContentProjectionService` 把组件或模板投影到给定的容器中,它还为组件或模板传递上下文.
+
+```js
+const strategy = PROJECTION_STRATEGY.ProjectComponentToContainer(
+ SomeComponent,
+ viewContainerRefOfTarget,
+ { someProp: "SOME_VALUE" }
+);
+
+const componentRef = this.contentProjectionService.projectContent(strategy);
+```
+
+在上面的示例中,`viewContainerRefOfTarget`(它是一个`ViewContainerRef` 实例)将被清除,并把 `SomeComponent` 组件放在其中. 另外将应用给定的上下文,因此组件的 `someProp` 被设置为 `SOME_VALUE`.
+
+> 你应该总是返回 `ComponentRef` 或 `EmbeddedViewRef` ,因为它是对投影内容的引用,在你需要时使用该引用销毁它们.
+
+请参考[ProjectionStrategy](./Projection-Strategy.md)查看所有可用的投影策略以及如何构建自己的投影策略.
+
+## API
+
+### projectContent
+
+```js
+projectContent | TemplateRef>(
+ projectionStrategy: ProjectionStrategy,
+ injector = this.injector,
+): ComponentRef | EmbeddedViewRef
+```
+
+- `projectionStrategy` 参数是此处的要点,在上面进行了说明.
+- `injector` 参数是 `Injector` 实例,你可以传递到投影内容. 在 `TemplateProjectionStrategy` 并没有使用到它.
+
+## 下一步是什么?
+
+- [TrackByService](./Track-By-Service.md)
\ No newline at end of file
diff --git a/docs/zh-Hans/UI/Angular/Content-Security-Strategy.md b/docs/zh-Hans/UI/Angular/Content-Security-Strategy.md
new file mode 100644
index 0000000000..7e419f8ab7
--- /dev/null
+++ b/docs/zh-Hans/UI/Angular/Content-Security-Strategy.md
@@ -0,0 +1,55 @@
+# ContentSecurityStrategy
+
+`ContentSecurityStrategy` 是@abp/ng.core包暴露出的抽象类. 它可以根据[内容安全策略](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)帮助你将内联脚本或样式标记为安全.
+
+## API
+
+### 构造函数
+
+```js
+constructor(public nonce?: string)
+```
+
+- `nonce` 启用将内联脚本或样式列入白名单,避免在[script-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Unsafe_inline_script)和[style-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src#Unsafe_inline_styles)指令中使用 `unsafe-inline`.
+
+### applyCSP
+
+```js
+applyCSP(element: HTMLScriptElement | HTMLStyleElement): void
+```
+
+该方法将上述属性映射到给定`element`.
+
+## LooseContentSecurityPolicy
+
+`LooseContentSecurityPolicy` 是扩展了 `ContentSecurityStrategy` 的类. 它需要 `nonce` 和带有给定 `