Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update todo tutorials document #8802

Merged
merged 1 commit into from
Apr 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/en/Tutorials/Todo/Index.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ Open the `Index.cshtml` file in the `Pages` folder of the *TodoApp.Web* project
</div>
````

We are using ABP's [card tag helper](../../UI/AspNetCore/Tag-Helpers/Cards.md) to create a simple card view. You could directly use the standard bootstrap HTML structure, however the ABP [tag helpers]() make it much easier and type safe.
We are using ABP's [card tag helper](../../UI/AspNetCore/Tag-Helpers/Cards.md) to create a simple card view. You could directly use the standard bootstrap HTML structure, however the ABP [tag helpers](../../UI/AspNetCore/Tag-Helpers/Index.md) make it much easier and type safe.

This page imports a CSS and a JavaScript file, so we should also create them.

Expand Down
93 changes: 48 additions & 45 deletions docs/zh-Hans/Tutorials/todo/Index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
}
````

这是一个单独的部分,使用ABP框架构建简单todo应用程序的快速入门教程.这是一个最终应用的截图:
这是一个单独的部分,使用ABP框架构建简单待办事项应用程序的快速入门教程.这是一个最终应用的截图:

![todo-list](todo-list.png)

你可以从已完成的项目里找到源代码,[这里](https://github.com/abpframework/abp-samples/tree/master/TodoApp).
你可以在[这里](https://github.com/abpframework/abp-samples/tree/master/TodoApp)找到已完成的项目源代码.

## 先决条件

* 一个集成开发环境 (比如: [Visual Studio](https://visualstudio.microsoft.com/vs/)) 它需要支持 [.NET 5.0+](https://dotnet.microsoft.com/download/dotnet) 的开发.
Expand Down Expand Up @@ -117,10 +118,10 @@ npm start

一切就绪.我们可以开始编码了!

## Domain Layer 领域层
## 领域层

此应用程序只有一个 [实体](../../Entities.md) 我们开始创建它. 在*TodoApp.Domain*项目中创建一个新的 `TodoItem` 类:

此应用程序只有一个 [entity](../../Entities.md) and we are starting by creating it. Create a new `TodoItem` class inside the *TodoApp.Domain* project:
我们开始创建它. 在*TodoApp.Domain*项目中创建一个新的 `TodoItem` 类:
````csharp
using System;
using Volo.Abp.Domain.Entities;
Expand All @@ -135,11 +136,12 @@ namespace TodoApp
````

`BasicAggregateRoot` 是创建根实体的最简单的基类之一,`Guid` 是这里实体的主键 (`Id`).

## Database Integration 数据库集成

{{if DB=="EF"}}

下一步是设置 [Entity Framework Core](../../Entity-Framework-Core.md) 配置.
下一步是配置 [Entity Framework Core](../../Entity-Framework-Core.md).

### Mapping Configuration 映射配置

Expand All @@ -165,7 +167,7 @@ public static void ConfigureTodoApp(this ModelBuilder builder)

我们已经将 `TodoItem` 实体映射到数据库中的 `TodoItems` 表.

### Code First Migrations 代码优先迁移
### 代码优先迁移

解决方案启动模版已经配置为使用Entity Framework Core [Code First 迁移](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations).由于我们已经更改了数据库映射配置,因此我们应该创建一个新的迁移并将更改应用于数据库.

Expand All @@ -189,6 +191,7 @@ dotnet ef database update
{{else if DB=="Mongo"}}

下一步是设置 [MongoDB](../MongoDB.md) 配置.在 *TodoApp.MongoDB* 项目的 `MongoDb` 文件夹中打开 `TodoAppMongoDbContext` 类,并进行以下更改;

1. 向类添加新属性:

````csharp
Expand All @@ -206,17 +209,17 @@ modelBuilder.Entity<TodoItem>(b =>

{{end}}

现在,我们可以使用ABP仓储来保存和检索todo列表项了,就像我们将在下一节中做的那样.
现在,我们可以使用ABP仓储来保存和检索待办事项列表项了,就像我们将在下一节中做的那样.

## Application Layer 应用层
## 应用层

[Application Service应用服务](../../Application-Services.md) 用于执行应用程序的用例.我们需要执行以下用例;
[应用服务](../../Application-Services.md) 用于执行应用程序的用例.我们需要执行以下用例;

* 获取待办事项列表
* 创建新的todo项
* 删除现有的todo项目
* 创建新的待办事项
* 删除现有的待办事项

### Application Service Interface 应用服务接口
### 应用服务接口

我们可以从为应用程序服务定义一个接口开始.在 *TodoApp.Application.Contracts* 项目中创建一个新的 `ITodoAppService` 接口,如下所示:

Expand All @@ -237,9 +240,9 @@ namespace TodoApp
}
````

### Data Transfer Object 数据传输对象
### 数据传输对象

`GetListAsync` and `CreateAsync` methods return `TodoItemDto`. Applications Services typically gets and returns DTOs ([Data Transfer Objects](../../Data-Transfer-Objects.md)) instead of entities. So, we should define the DTO class here. Create a new `TodoItemDto` class inside the *TodoApp.Application.Contracts* project:
`GetListAsync` `CreateAsync` 方法返回 `TodoItemDto`. 通常应用服务获取或返回的是 DTO ([数据传输对象](../../Data-Transfer-Objects.md)) 而不是直接获取或返回实体对象. 所以,我们应该在此定义 DTO(数据传输对象) 类. 在 *TodoApp.Application.Contracts* 项目中创建一个名为 `TodoItemDto` 的类:

````csharp
using System;
Expand All @@ -254,9 +257,9 @@ namespace TodoApp
}
````

这是一个非常简单的DTO类,与我们的 `TodoItem` 实体匹配.我们接下来实现 `ITodoAppService` 接口.
这是一个非常简单的DTO类,与我们的 `TodoItem` 实体相对应.我们接下来实现 `ITodoAppService` 接口.

### Application Service Implementation 应用服务实现
### 应用服务实现

在 *TodoApp.Application* 项目内部创建一个 `TodoAppService` 类,如下所示:

Expand Down Expand Up @@ -284,11 +287,11 @@ namespace TodoApp
}
````

该类继承自ABP框架的 `ApplicationService` 类,并实现之前定义的 `ITodoAppService`接口.ABP为实体提供默认的通用 [repositories存储库](../repositories.md).我们可以使用它们来执行基本的数据库操作.此类 [injects 注入](../Dependency-Injection.md) `IRepository<TodoItem, Guid>` `TodoItem` 实体的默认存储库.我们将使用它来实现之前描述的用例.
该类继承自ABP框架的 `ApplicationService` 类,并实现了之前定义的 `ITodoAppService`接口.ABP为实体提供默认的通用的 [仓储](../repositories.md).我们可以使用它们来执行基本的数据库操作. 这个类 [注入](../Dependency-Injection.md) `IRepository<TodoItem, Guid>` 它是 `TodoItem` 实体的默认存储库.我们将使用它来实现之前描述的用例.

#### 获取所有Todo项列表
#### 获取所有待办事项列表

Let's start by implementing the `GetListAsync` method:
让我们开始实现 `GetListAsync` 方法:

````csharp
public async Task<List<TodoItemDto>> GetListAsync()
Expand All @@ -305,7 +308,7 @@ public async Task<List<TodoItemDto>> GetListAsync()

我们只是简单的从数据库中获取完整的 `TodoItem` 列表,将它们映射到 `TodoItemDto` 对象并作为结果返回.

#### 创建一个新的Todo项
#### 创建一个新的待办事项

下一个方法是 `CreateAsync`,我们可以像如下所示来实现:

Expand All @@ -324,9 +327,9 @@ public async Task<TodoItemDto> CreateAsync(string text)
}
````

Repository的 `InsertAsync` 方法将给定的 `TodoItem` 插入数据库,并返回相同的 `TodoItem` 对象.它还设置 `Id`,因此我们可以在返回对象上使用它.我们只是通过从新的 `TodoItem` 实体创建返回 `TodoItemDto`.
仓储的 `InsertAsync` 方法将给定的 `TodoItem` 插入数据库,并返回相同的 `TodoItem` 对象.它还设置了 `Id`,因此我们可以在返回对象上使用它.我们只是通过从新的 `TodoItem` 实体创建和返回 `TodoItemDto`.

#### 删除一个子项
#### 删除待办事项

最后,我们可以将 `DeleteAsync` 实现为以下代码块:

Expand All @@ -337,9 +340,9 @@ public async Task DeleteAsync(Guid id)
}
````

应用程序服务已准备好从UI层使用.
至此,应用程序服务已准备好了让UI层来使用.

## User Interface Layer 用户界面层
## 用户界面层

是时候在UI上显示待办事项了!在开始编写代码之前,最好记住我们正在尝试构建的内容.这是最终UI的示例屏幕截图:

Expand Down Expand Up @@ -378,7 +381,7 @@ namespace TodoApp.Web.Pages
}
````

此类使用 `ITodoAppService` 获取todo项目列表并分配 `TodoItems` 属性.我们将用它来渲染razor页面上的待办事项.
此类使用 `ITodoAppService` 获取待办事项目列表并将它赋值给 `TodoItems` 属性.我们将用它来渲染razor页面上的待办事项目列表.

### Index.cshtml

Expand Down Expand Up @@ -424,7 +427,7 @@ namespace TodoApp.Web.Pages
</div>
````

我们使用ABP的 [card tag helper 卡片标签助手](../UI/AspNetCore/标签助手/Cards.md) 创建一个简单的卡片视图.你可以直接使用标准的bootstrap HTML,不过ABP的 [tag helpers 标签助手]() 使它更容易并且类型安全.
我们使用ABP的 [卡片标签助手](../../UI/AspNetCore/Tag-Helpers/Cards.md) 创建一个简单的卡片视图.你可以直接使用标准的bootstrap HTML, 不过ABP的[标签助手](../../UI/AspNetCore/Tag-Helpers/Index.md) 使它更简单并且类型安全.

这个页面要导入一个CSS和一个JavaScript文件,所以我们也应该创建它们.

Expand Down Expand Up @@ -461,15 +464,15 @@ $(function () {
});
````

在第一部分中,我们在todo项目附近注册点击垃圾图标的事件,删除服务器上的相关项目并在UI上显示通知.另外,我们从DOM中删除已删除的项目,因此我们不需要刷新页面.
在第一部分中,我们在待办事项目附近注册点击删除图标所要触发的事件,删除服务器上的相关待办事项并在UI上显示通知.另外,我们从DOM中删除已删除的项,因此我们不需要刷新页面.

在第二部分中,我们在服务器上创建一个新的todo事项.如果成功,我们将操纵DOM以将新的 `<li>` 元素插入todo列表.这样,创建新的todo条目后就不用刷新整个页面了.
在第二部分中,我们在服务器上创建一个新的待办事项.如果成功,我们将操纵DOM以将新的 `<li>` 元素插入todo列表.这样,创建新的待办事项后就不用刷新整个页面了.

这里有趣的部分是我们如何与服务器通信.请参阅 *Dynamic JavaScript Proxies & Auto API Controllers 动态JavaScript代理和自动API控制器* 部分,以了解其工作原理.但是现在让我们继续并完成申请.
这里有趣的部分是我们如何与服务器通信.请参阅 *动态JavaScript代理和自动API控制器* 部分,以了解其工作原理.但是现在让我们继续并完成这个应用程序.

### Index.css

最后要做的,请打开 *TodoApp.Web* 项目的 `Pages` 文件夹中的 `Index.css` 文件,并替换为以下内容:
来到最后要做的工作,请打开 *TodoApp.Web* 项目的 `Pages` 文件夹中的 `Index.css` 文件,并替换为以下内容:

````css
#TodoList{
Expand Down Expand Up @@ -498,15 +501,15 @@ $(function () {
}
````

这是todo页面的简单样式.我们相信你可以做得更好 :)
这是待办事项页面的简单样式.我们相信你可以做得更好 :)

现在,你可以再次运行应用程序以查看结果.

### Dynamic JavaScript Proxies & Auto API Controllers 动态JavaScript代理和自动应用编程接口控制器

在 `Index.js` 文件中,我们使用了 `todoApp.todo.delete(...)` 和 `todoApp.todo.create(...)` 函数与服务器通信.这些函数是由ABP框架动态创建的,这要归功于 [Dynamic JavaScript Client Proxy 动态JavaScript客户端代理](../UI/AspNetCore/Dynamic-JavaScript-Proxies.md) 系统.他们对服务器执行HTTP API调用并返回承诺,因此你可以像上面所做的那样注册对 `then` 函数的回调.
在 `Index.js` 文件中,我们使用了 `todoApp.todo.delete(...)` 和 `todoApp.todo.create(...)` 函数与服务器通信.这些函数是由ABP框架动态创建的,这要归功于 [动态JavaScript客户端代理](../UI/AspNetCore/Dynamic-JavaScript-Proxies.md) 系统.他们对服务器执行HTTP API调用并返回承诺,因此你可以像上面所做的那样注册对 `then` 函数的回调.

但是,你可能会问我们还没有创建任何API控制器,那么服务器如何处理这些请求?这个问题给我们带来了ABP框架的 [Auto API Controller 自动API控制器](../API/Auto-API-Controllers.md) 功能.它通过约定自动将应用程序服务转换为API Controllers(API控制器).
但是,你可能会问我们还没有创建任何API控制器,那么服务器如何处理这些请求呢? 这个问题为我们引出了ABP框架的 [自动API控制器](../API/Auto-API-Controllers.md) 功能.它通过约定自动将应用程序服务转换为API Controllers(API控制器).

如果通过在应用程序中输入 `/swagger` URL来打开 [swagger UI](https://swagger.io/tools/ Swagger-ui/),则可以看到Todo API:

Expand Down Expand Up @@ -555,11 +558,11 @@ namespace TodoApp.Blazor.Pages
}
````

这个类使用 `ITodoAppService` 对todo项执行操作.它在创建和删除操作后操纵 `TodoItems` 列表.这样,我们不需要从服务器刷新整个todo列表.
这个类使用 `ITodoAppService` 对待办事项执行操作.它在创建和删除操作后操纵 `TodoItems` 列表.这样,我们不需要从服务器刷新整个todo列表.

{{if UI=="Blazor"}}

请参阅下面的 *Dynamic C# Proxies & Auto API Controllers 动态C # 代理和自动API控制器* 部分,以了解如何从浏览器上运行的Blazor应用程序注入和使用应用程序服务接口!但是现在,让我们继续并完成这个应用.
请参阅下面的 *动态C # 代理和自动API控制器* 部分,了解如何从浏览器上运行的Blazor应用程序注入和使用应用程序服务接口!但是现在,让我们继续并完成这个应用.

{{end # Blazor}}

Expand Down Expand Up @@ -637,19 +640,19 @@ namespace TodoApp.Blazor.Pages
}
````

这是todo页面的简单样式.我们相信你可以做得更好 :)
这是待办事项页面的简单样式.我们相信你可以做得更好 :)

现在,你可以再次运行应用程序以查看结果.

{{if UI=="Blazor"}}

### Dynamic C# Proxies & Auto API Controllers 动态C#代理和自动应用编程接口控制器

在 `Index.razor.cs` 文件中,我们已经注入 (使用 `[Inject]` 特性),并像使用本地服务一样使用 `ITodoAppService`.请记住,当此应用程序服务的实现在服务器上运行时,Blazor应用程序正在浏览器上运行.
在 `Index.razor.cs` 文件中,我们已经注入(使用 `[Inject]` 特性)并像使用本地服务一样使用 `ITodoAppService`.请记住,当此应用程序服务的实例在服务器上运行的同时,Blazor应用程序正在浏览器上运行.

这个神奇的过程是由ABP框架的 [Dynamic C# Client Proxy 动态C#客户端代理](../API/Dynamic-CSharp-API-Clients.md) 系统完成的.它使用标准的 `HttpClient` 并向远程服务器执行HTTP API请求.它还为我们处理所有标准任务,包括授权,JSON序列化和异常处理.
这个神奇的过程是由ABP框架的 [动态C#客户端代理](../API/Dynamic-CSharp-API-Clients.md) 系统完成的.它使用标准的 `HttpClient` 并向远程服务器执行HTTP API请求.它还为我们处理所有标准任务,包括授权,JSON序列化和异常处理.

但是,你可能会问我们还没有创建任何API控制器,那么服务器如何处理这些请求?这个问题给我们带来了ABP框架的 [Auto API Controller 自动API控制器](../API/Auto-API-Controllers.md) 功能.它通过约定自动将应用程序服务转换为API控制器.
但是,你可能会问我们还没有创建任何API控制器,那么服务器如何处理这些请求呢? 这个问题为我们引出了ABP框架的 [自动API控制器](../API/Auto-API-Controllers.md) 功能.它通过约定自动将应用程序服务转换为API控制器.

如果你运行 `TodoApp.HttpApi.Host` 应用程序,你可以看到Todo API:

Expand All @@ -659,7 +662,7 @@ namespace TodoApp.Blazor.Pages

{{else if UI=="NG"}}

### Service Proxy Generation 服务代理生成
### 服务代理生成

ABP提供了一个方便的功能,可以自动创建客户端服务,轻松使用服务器提供的HTTP APIs.

Expand Down Expand Up @@ -733,7 +736,7 @@ export class HomeComponent implements OnInit {

````

我们已经使用 `todoService` 来获取todo项目的列表,并将返回值分配给 `todoItems` 数组.我们还添加了 `create`和 `delete` 方法.这些方法将在视图端使用.
我们已经实现了使用 `todoService` 来获取待办事项目列表,并将返回值赋值给 `todoItems` 数组.我们还添加了 `create`和 `delete` 方法.这些方法将在视图端使用.

### home.component.html

Expand Down Expand Up @@ -800,19 +803,19 @@ export class HomeComponent implements OnInit {
}
````

这是todo页面的简单样式.我们相信你可以做得更好 :)
这是待办事项页面的简单样式.我们相信你可以做得更好 :)

现在,你可以再次运行应用程序以查看结果.

{{end}}

## 总结

在本教程中,我们构建了一个非常简单的应用程序来抢先探究ABP框架的新特性.如果你想构建一个现实的应用程序,请查看 [应用程序开发教程](../Part-1.md),其中涵盖了实际web应用程序开发的所有方面.
在本教程中,我们构建了一个非常简单的应用程序来抢先探究ABP框架的新特性.如果你想构建一个实际场景的应用程序,请查看 [应用程序开发教程](../Part-1.md),其中涵盖了实际web应用程序开发的所有方面.

## 源代码

你可以找到完成的应用程序的源代码 [这里](https://github.com/abpframework/abp-samples/tree/master/TodoApp).
你可以在[这里](https://github.com/abpframework/abp-samples/tree/master/TodoApp)获取到完整的应用程序源代码.

## 另请参见

Expand Down