ABP-Book Store Application中文讲解 - Part 2: The Book List Page

news2025/5/17 1:49:52

本章用于介绍如何创建Book List Page。

 TBD

1. 汇总

ABP-Book Store Application中文讲解-汇总-CSDN博客

2. 前一章 

ABP-Book Store Application中文讲解 - Part 1: Creating the Server Side

项目之间的引用关系。

目录

1. 多语言配置 

1.1 zh-Hans.json 

1.2 en.json

2. 添加proxy

2.1 前置条件

2.2 利用abp自动生成angular端的service

3. 创建Books页面

3.1 利用ng generate生成页面组件

3.2 在route.provider.ts中配置菜单

3.2 添加页面内容到BookComponent

3.2.1 book.component.ts 

3.2.1.1 非standalone模式

3.2.1.2 standalone 模式 (推荐此模式)

 3.2.2 book.component.html

4.启动项目

5. Angular推荐使用全独立模式避免NgModule的干扰

 6. 继续学习


1. 多语言配置 

在开始做UI的开发前,我们需要对UI端的一些信息做多语言处理。Localization\BookStore里面有很多json文件。

zh-Hans.json简体中文

zh-Hant.json繁体中文

en.json English

此处根据自己需要自行添加。不用的语言可以自行删除。

需要注意的是要保证你所更改的json文件里面的key一一对应。

1.1 zh-Hans.json 

{
  "culture": "zh-Hans",
  "texts": {
    "AppName": "BookStore",
    "Menu:Home": "首页",
    "Welcome": "欢迎",
    "LongWelcomeMessage": "欢迎使用本应用程序。这是一个基于 ABP 框架的启动项目。更多信息,请访问 abp.io。",
    // 以下内容是新增内容
    "Menu:BookStore": "Book Store",
    "Menu:Books": "Books",
    "Actions": "操作",
    "Close": "关闭",
    "Delete": "删除",
    "Edit": "编辑",
    "PublishDate": "发布日期",
    "NewBook": "新增书",
    "Name": "名字",
    "Type": "类型",
    "Price": "价格",
    "CreationTime": "新建日期",
    "AreYouSure": "你确定吗?",
    "AreYouSureToDelete": "你确定你要删除此条目吗?",
    "Enum:BookType.0": "未定义",
    "Enum:BookType.1": "冒险",
    "Enum:BookType.2": "传记",
    "Enum:BookType.3": "反乌托邦",
    "Enum:BookType.4": "奇幻",
    "Enum:BookType.5": "恐怖",
    "Enum:BookType.6": "科学",
    "Enum:BookType.7": "科幻",
    "Enum:BookType.8": "诗歌"
  }
}

1.2 en.json

{
  "Culture": "en",
  "Texts": {
    "Menu:Home": "Home",
    "Welcome": "Welcome",
    "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP. For more information, visit abp.io.",
    // 以下内容是新增内容
    "Menu:BookStore": "Book Store",
    "Menu:Books": "Books",
    "Actions": "Actions",
    "Close": "Close",
    "Delete": "Delete",
    "Edit": "Edit",
    "PublishDate": "Publish date",
    "NewBook": "New book",
    "Name": "Name",
    "Type": "Type",
    "Price": "Price",
    "CreationTime": "Creation time",
    "AreYouSure": "Are you sure?",
    "AreYouSureToDelete": "Are you sure you want to delete this item?",
    "Enum:BookType.0": "Undefined",
    "Enum:BookType.1": "Adventure",
    "Enum:BookType.2": "Biography",
    "Enum:BookType.3": "Dystopia",
    "Enum:BookType.4": "Fantastic",
    "Enum:BookType.5": "Horror",
    "Enum:BookType.6": "Science",
    "Enum:BookType.7": "Science fiction",
    "Enum:BookType.8": "Poetry"
  }
}

2. 添加proxy

2.1 前置条件

打开cmd.exe,输入ng --version查看是否安装了@angular/cli,如果没安装,可通过以下命令安装。

npm install -g @angular/cli

利用abp的命令自动生成proxy。此时有个前置条件是abp的命令只能调用dotnet tool下的API启动方式,无法调用基于IIS Express启动下的API。

即需要将Acme.BookStore.HttpApi.Host启动模式选择Acme.BookStore.HttpApi.Host

 设置好后,点击F5启动程序。

2.2 利用abp自动生成angular端的service

vs code 打开angular目录,ctrl+`打开Terminal window, 然后输入一下命令敲回车。

3. 创建Books页面

此处UI组件用的是Ng Bootstrap, datatable组件用的是Ngx-Datatable.或者你可以使用PrimeNG - Angular UI Component Library

3.1 利用ng generate生成页面组件

此处利用ng命令去自动生成相关的ts文件。

ng generate module book --module app --routing --route books

以上代码创建book module和routing并指定route是books,并自动创建book相关的component,module和router,router会被自动添加到app-routing.module.ts中。

如果是你手动创建的component或者module,需要自己手动添加到app-routing.module.ts中。

loadChildren: () => import('./book/book.module').then(m => m.BookModule)这种方式是lazy-load的方式,只有在用户点击对应的页面的时候才会加载对应页面的js、css、html等。

3.2 在route.provider.ts中配置菜单

打开src/app/route.provider.ts,添加book-store 和books.

RoutesService是ABP用于配置主菜单和路径的,不是angualr原生。

  • path 访问此页面的URL
  • name 本地化菜单名字(localization document ).如果你不需要本地化,直接写死也可以的
  • iconClass 菜单图标 (你可以从Font Awesome 上面找到你需要的icons).
  • order 菜单的顺序.
  • layout BooksModule's routes布局方式 (提供了三种布局方式: eLayoutType.applicationeLayoutType.account or eLayoutType.empty).

后面我会单独针对ABP的前端UI-Angular UI写一系列的文章ABP User Interface-Angular UI中文详解-CSDN博客。

import { RoutesService, eLayoutType } from '@abp/ng.core';
import { APP_INITIALIZER } from '@angular/core';

export const APP_ROUTE_PROVIDER = [
  { provide: APP_INITIALIZER, useFactory: configureRoutes, deps: [RoutesService], multi: true },
];

function configureRoutes(routesService: RoutesService) {
  return () => {
    routesService.add([
      {
        path: '/',
        name: '::Menu:Home',
        iconClass: 'fas fa-home',
        order: 1,
        layout: eLayoutType.application,
      },
      {
        path: '/book-store',
        name: '::Menu:BookStore',
        iconClass: 'fas fa-book',
        order: 2,
        layout: eLayoutType.application,
      },
      {
        path: '/books',
        name: '::Menu:Books',
        // iconClass: 'fas fa-user',
        parentName: '::Menu:BookStore',
        order: 3,
        layout: eLayoutType.application,
      }
    ]);
  };
}

3.2 添加页面内容到BookComponent

添加页面内容。

导入并注册BookService和ListService.

BookService是利用ng generate-proxy生成的服务

ListService是ABP团队创建的,提供了分页、排序和查询。ListService不是注册在root级别,他是component级别的,即component销毁后,当前页面的ListService会同步销毁。

具体可以在Working with Lists | ABP.IO Documentation中找到,后序我会在ABP User Interface-Angular UI中文详解-CSDN博客提供中文版本的使用说明。

3.2.1 book.component.ts 

3.2.1.1 非standalone模式
import { Component, OnInit } from '@angular/core';
import { ListService, PagedResultDto } from '@abp/ng.core';  // Import ListService and PagedResultDto
import { BookService, BookDto } from '../proxy/books';  // Import your BookService and BookDto model
import { SharedModule } from '../shared/shared.module';

@Component({
  selector: 'app-book',
  templateUrl: './book.component.html',
  styleUrl: './book.component.scss',
  standalone: false, // 标记为独立组件
  // imports: [SharedModule], // 导入需要的模块
  providers: [ListService]  // Provide ListService for this component
})
export class BookComponent implements OnInit {
  book = { items: [], totalCount: 0 } as PagedResultDto<BookDto>;  // Initialize books as an empty PagedResultDto

  constructor(private bookService: BookService, public readonly list: ListService) { }  // Inject BookService and ListService

  ngOnInit() {  // Use ngOnInit to fetch books when the component initializes
    this.list.hookToQuery(this.bookService.getList).subscribe((response) => {  // Hook to the query and subscribe to the response
      this.book = response;  // Assign the response to books
    });
  }
}

还需要在book.module.ts声明BookComponent

import { NgModule } from '@angular/core';
// import { CommonModule } from '@angular/common';

import { SharedModule } from '../shared/shared.module';
import { BookRoutingModule } from './book-routing.module';
import { BookComponent } from './book.component';

@NgModule({
  declarations: [
    BookComponent
  ],
  imports: [
    BookRoutingModule,
    SharedModule// shared module already export CommonModule, so we don't need to import it again.
  ]
})
export class BookModule { }
3.2.1.2 standalone 模式 (推荐此模式)

如果使用的是Angualr 14+, 则需要改成如下所示:

import { Component, OnInit } from '@angular/core';
import { ListService, PagedResultDto } from '@abp/ng.core';  // Import ListService and PagedResultDto
import { BookService, BookDto } from '../proxy/books';  // Import your BookService and BookDto model
import { SharedModule } from '../shared/shared.module';

@Component({
  selector: 'app-book',
  templateUrl: './book.component.html',
  styleUrl: './book.component.scss',
  standalone: true, // 标记为独立组件
  imports: [SharedModule], // standalone: true导入需要的模块
  providers: [ListService]  // Provide ListService for this component
})
export class BookComponent implements OnInit {
  book = { items: [], totalCount: 0 } as PagedResultDto<BookDto>;  // Initialize books as an empty PagedResultDto

  constructor(private bookService: BookService, public readonly list: ListService) { }  // Inject BookService and ListService

  ngOnInit() {  // Use ngOnInit to fetch books when the component initializes
    this.list.hookToQuery(this.bookService.getList).subscribe((response) => {  // Hook to the query and subscribe to the response
      this.book = response;  // Assign the response to books
    });
  }
}

 book.module.ts移除BookComponent声明

import { NgModule } from '@angular/core';
import { SharedModule } from '../shared/shared.module';
import { BookRoutingModule } from './book-routing.module';

@NgModule({
  declarations: [
  ],
  imports: [
    BookRoutingModule,
    SharedModule// shared module already export CommonModule, so we don't need to import it again.
  ]
})
export class BookModule { }

 3.2.2 book.component.html

Tips: 比如你想实现<div class="card"></div>, 此时你只需要输入div.card然后直接敲Tab,vs code可以帮你自动生成。

类似的输入h5.card-title敲Tab自动生成<h5 class="card-title"></h5>

4.启动项目

后端API需要先启动。

npm start重新编译后,浏览器会自动打开,然后左侧会显示Book Store菜单。

展开后选择Books,加载数据完成如下图所示:

5. Angular推荐使用全独立模式避免NgModule的干扰

// AppComponent.ts(独立根组件)
import { Component } from '@angular/core';
import { BookComponent } from './book/book.component';
import { BrowserModule } from '@angular/platform-browser'; // 若需导入模块,需在 imports 中声明

@Component({
  selector: 'app-root',
  template: `<app-book></app-book>`,
  imports: [BrowserModule, BookComponent], // 导入依赖的模块和独立组件。类似把app.module.ts中的imports都放在此处
  standalone: true // 根组件标记为独立
})
export class AppComponent { }

 6. 继续学习

ABP-Book Store Application中文讲解 - Part 3: Creating, Updating and Deleting Books

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2377273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

08 web 自动化之 PO 设计模式详解

文章目录 一、什么是 POM二、如何基于 POM 进行自动化框架架构&#xff1f;1、base 层封装2、pageobjects 层封装3、TestCases 层封装 三、元素和方法分离&数据分离1、哪些部分可以进行分离2、示例代码 四、总结 一、什么是 POM POM page object model 页面对象模型 WEB 自…

langchain4j集成QWen、Redis聊天记忆持久化

langchain4j实现聊天记忆默认是基于进程内存的方式&#xff0c;InMemoryChatMemoryStore是具体的实现了&#xff0c;是将聊天记录到一个map中&#xff0c;如果用户大的话&#xff0c;会造成内存溢出以及数据安全问题。位了解决这个问题 langchain4提供了ChatMemoryStore接口&am…

WebGL图形编程实战【7】:变换流水线 × 坐标系与矩阵精讲

变换流水线 #mermaid-svg-Omabd9LSNCdIvWqB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Omabd9LSNCdIvWqB .error-icon{fill:#552222;}#mermaid-svg-Omabd9LSNCdIvWqB .error-text{fill:#552222;stroke:#552222;…

DVWA靶场通关笔记-SQL注入(SQL Injection Medium级别)

目录 一、SQL Injection 二、代码审计&#xff08;Medium级别&#xff09; 1、源码分析 &#xff08;1&#xff09;index.php &#xff08;2&#xff09;Medium.php 2、渗透思路 &#xff08;1&#xff09;SQL安全问题分析 &#xff08;2&#xff09;SQL渗透思路 三、…

vue异步导入

vue的异步导入 大家开发vue的时候或多或少路由的异步导入 component: () >import(“/views/A_centerControl/intelligent-control/access-user-group”),当然这是路由页面&#xff0c;那么组件也是可以异步导入的 使用方式 组件的异步导入非常简单&#xff0c;主要是一个…

2025年,如何制作并部署一个完整的个人博客网站

欢迎访问我的个人博客网站&#xff1a;欢迎来到Turnin的个人博客 github开源地址&#xff1a;https://github.com/Re-restart/my_website 前言 2024年年初&#xff0c;从dji实习回来之后&#xff0c;我一直想着拓宽自己的知识边界。在那里我发现虽然大家不用java&#xff0c;…

腾讯云运营开发 golang一面

redis为什么单线程会快 每秒10w吞吐量 io多路复用 一个文件描述符整体拷贝&#xff1b;调用epoll_ctl 单个传递 内核遍历文件描述符判断是否有事件发送&#xff1b;回调函数列表维护 修改有事件发送的socket为可读或可写&#xff0c;返回整个文件描述符&#xff1b;返回链…

一个简单的静态页面

这个页面采用了现代化的 UI 设计&#xff0c;包括卡片式布局、微交互动画、分层设计和响应式结构。页面结构清晰&#xff0c;包含导航栏、英雄区域、功能介绍、产品特性、用户评价和联系表单等完整组件&#xff0c;可作为企业官网或产品介绍页面的基础模板。 登录后复制 <!D…

使用 163 邮箱实现 Spring Boot 邮箱验证码登录

使用 163 邮箱实现 Spring Boot 邮箱验证码登录 本文将详细介绍如何使用网易 163 邮箱作为 SMTP 邮件服务器&#xff0c;实现 Spring Boot 项目中的邮件验证码发送功能&#xff0c;并解决常见配置报错问题。 一、为什么需要邮箱授权码&#xff1f; 出于安全考虑&#xff0c;大…

多模态大语言模型arxiv论文略读(六十八)

Image-of-Thought Prompting for Visual Reasoning Refinement in Multimodal Large Language Models ➡️ 论文标题&#xff1a;Image-of-Thought Prompting for Visual Reasoning Refinement in Multimodal Large Language Models ➡️ 论文作者&#xff1a;Qiji Zhou, Ruoc…

APS「多目标平衡算法」如何破解效率与弹性的永恒博弈

APS&#xff08;高级计划与排程&#xff09;系统作为企业智能制造的核心引擎&#xff0c;通过整合需求预测、产能规划、生产调度、物料管理及数据分析等模块&#xff0c;构建了覆盖产品全生产流程的“感知-决策-执行-优化”闭环体系。 精准需求预测 APS系统通过构建需求特征数…

网张实验操作-防火墙+NAT

实验目的 了解防火墙&#xff08;ENSP中的USG5500&#xff09;域间转发策略配置、NAT&#xff08;与路由器NAT配置命令不同&#xff09;配置。 网络拓扑 两个防火墙连接分别连接一个内网&#xff0c;中间通过路由器连接。配置NAT之后&#xff0c;内网PC可以ping公网&#xf…

05 web 自动化之 selenium 下拉鼠标键盘文件上传

文章目录 一、下拉框操作二、键盘操作三、鼠标操作四、日期控件五、滚动条操作六、文件上传七、定位windows窗口及窗口的元素总结&#xff1a;页面及元素常用操作 一、下拉框操作 from selenium.webdriver.support.select import Select import time from selenium.webdriver.…

Spring Cloud探索之旅:从零搭建微服务雏形 (Eureka, LoadBalancer 与 OpenFeign实战)

引言 大家好&#xff01;近期&#xff0c;我踏上了一段深入学习Spring Cloud构建微服务应用的旅程。我从项目初始化开始&#xff0c;逐步搭建了一个具备服务注册与发现、客户端负载均衡以及声明式服务调用功能的基础微服务系统。本文旨在记录这一阶段的核心学习内容与实践成果…

当 AI 邂逅丝路:揭秘「丝路智旅」,用 RAG 重塑中阿文化旅游体验

目录 系统命名:丝路智旅 (Silk Road Intelligent Travel)系统概述系统架构设计系统功能模块技术选型:为何是它们?系统优势与特点未来展望与扩展总结在数字浪潮席卷全球的今天,古老的丝绸之路正在以一种全新的方式焕发生机。当深厚的文化底蕴遇上尖端的人工智能技术,会碰撞…

18.Excel数据透视表:第1部分创建数据透视表

一 什么是数据透视表 通过万花筒可以用不同的方式査看里面画面图像&#xff0c;在excel中可以将数据透视表看作是对准数据的万花筒&#xff0c;用不同角度去观察数据&#xff0c;也可以旋转数据&#xff0c;对数据进行重新排列&#xff0c;对大量的数据可以快速的汇总和建立交叉…

CSS AI 通义灵码 VSCode插件安装与功能详解

简介 在前端开发领域&#xff0c;页面调试一直是个繁琐的过程&#xff0c;而传统开发中美工与前端的对接也常常出现问题。如今&#xff0c;阿里云技术团队推出的通义灵码智能编码助手&#xff0c;为前端开发者带来了新的解决方案&#xff0c;让开发者可以像指挥者一样&#xf…

【Linux网络】TCP全连接队列

TCP 相关实验 理解 listen 的第二个参数 基于刚才封装的 TcpSocket 实现以下测试代码对于服务器, listen 的第二个参数设置为 1, 并且不调用 accept测试代码链接 test_server.cc #include "tcp_socket.hpp"int main(int argc, char* argv[]) {if (argc ! 3) {pri…

HTML 颜色全解析:从命名规则到 RGBA/HSL 值,附透明度设置与场景应用指南

一、HTML 颜色系统详解 HTML 中的颜色可以通过多种方式定义&#xff0c;包括颜色名称、RGB 值、十六进制值、HSL 值等&#xff0c;同时支持透明度调整。以下是详细分类及应用场景&#xff1a; 1. 颜色名称&#xff08;预定义关键字&#xff09; HTML 预定义了 140 个标准颜色名…

深度剖析多模态大模型中的视频编码器算法

写在前面 随着多模态大型语言模型(MLLM)的兴起,AI 理解世界的能力从静态的文本和图像,进一步拓展到了动态的、包含丰富时空信息的视频。视频作为一种承载了动作、交互、场景变化和声音(虽然本文主要聚焦视觉部分)的复杂数据形式,为 MLLM 提供了理解真实世界动态和因果关…