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, + }), + ); + //... + } +} +``` + +![Example Usage](./images/component-replacement.gif) + +### 如何替换布局 + +每个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` 和带有给定 `