回文集目录:JHipster一知半解
layout目录并非子模块,因而并没有包含module.ts文件,包含了整个工程的页面切分
main目录
该目录为angular程序的主界面控件,包括主界面划分和标题切换的能力
main.component.ts
其jhi-main为jhi-main,也就是说它会替换掉index里面的angular入口<jhi-main>标签内容,加入我们需要的组件内容。
constructor(
private jhiLanguageHelper: JhiLanguageHelper,
private router: Router
) {}
//从路由参数中获得pageTitle的属性值,如果没有就用默认的工程名,
private getPageTitle(routeSnapshot: ActivatedRouteSnapshot) {
let title: string = (routeSnapshot.data && routeSnapshot.data['pageTitle']) ? routeSnapshot.data['pageTitle'] : 'jhipsterSampleApplicationNg2App';
if (routeSnapshot.firstChild) {
title = this.getPageTitle(routeSnapshot.firstChild) || title;
}
return title;
}
ngOnInit() {
//注册监听路由变化的事件,当NavigationEnd事件才改标题。
this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd) {
//注意这里的update最终会调用translative服务,实现多语种支持。
this.jhiLanguageHelper.updateTitle(this.getPageTitle(this.router.routerState.snapshot.root));
}
});
}
main.component.html
<jhi-page-ribbon></jhi-page-ribbon>
<div>
<router-outlet name="navbar"></router-outlet>
</div>
<!--这里已经用了container-fluid和card jh-card,所以包含在各个子模块的html都只是简单的bootstrap的div即可-->
<div class="container-fluid">
<div class="card jh-card">
<router-outlet></router-outlet>
<router-outlet name="popup"></router-outlet>
</div>
<jhi-footer></jhi-footer>
</div>
整体页面分为3大块,最上面为<jhi-page-ribbon>块,当程序是微服务测试环境时显示,下面为navbar菜单区域。最下面为主体区域,有包含程序主体-<router-outlet>部分和foot两小块。
//TODO:页面的布局图,主界面画框
profiles目录
<jhi-page-ribbon>标签,根据从后端获取的profile,决定是否显示信息。
profile.service.ts
与后端api/profile-info进行交互,获取后端服务的profile信息
//返回一个Promise
getProfileInfo(): Promise<ProfileInfo> {
if (!this.profileInfo) {
//直接调用http.get方法通讯。
this.profileInfo = this.http.get(this.profileInfoUrl)
.map((res: Response) => {
const data = res.json();
//构造ProfileInfo结构体。
const pi = new ProfileInfo();
pi.activeProfiles = data.activeProfiles;
pi.ribbonEnv = data.ribbonEnv;
pi.inProduction = data.activeProfiles.includes('prod');
pi.swaggerEnabled = data.activeProfiles.includes('swagger');
return pi;
//http.get是Observable,所以要调用toPromise转换
}).toPromise();
}
return this.profileInfo;
}
page-ribbon.component.ts
//在Init时就获取Profile,也就是说,在打开页面必然加载<jhi-page-ribbon>,也就是说必然会调用profileService与后台交互,获取ProfileInfo
ngOnInit() {
this.profileService.getProfileInfo().then((profileInfo) => {
this.profileInfo = profileInfo;
this.ribbonEnv = profileInfo.ribbonEnv;
});
}
footer目录
footer.component.html和footer.component.ts比较简单,仅显示“This is your footer”这么一句话,具体工程应该加上网站地图,备案信息等。
error目录
error.route.ts
定义出现错误时候的路由地址,error和accessdenied两个url都会跳转到这个统一的提示页面ErrorComponent,唯一区别是accessdenied时候,route的data增加了一个error403: true的属性。
error.component.ts
ngOnInit() {
//从路由里面获取data,并把error403属性和errorMessage赋值到自己组件里面的属性中。
this.route.data.subscribe((routeData) => {
if (routeData.error403) {
this.error403 = routeData.error403;
}
if (routeData.errorMessage) {
this.errorMessage = routeData.errorMessage;
}
});
}
error.component.html
<div>
<div class="row">
<div class="col-md-4">
<span class="hipster img-fluid rounded"></span>
</div>
<div class="col-md-8">
//翻译error.title
<h1 jhiTranslate="error.title">Error Page!</h1>
//这里简单用了hidden指令,由于没有其他样式了,这么用倒是没什么问题。
//官方还是推荐用*ngIf,直接从dom树删除,这个比较display:none保险的的多。
<div [hidden]="!errorMessage">
<div class="alert alert-danger">{{errorMessage}}
</div>
</div>
<div [hidden]="!error403" class="alert alert-danger" jhiTranslate="error.http.403">You are not authorized to access this page.
</div>
</div>
</div>
</div>
TODO:附图。
navbar目录
navbar.route.ts
export const navbarRoute: Route = {
path: '',
component: NavbarComponent,
outlet: 'navbar'
};
注意:这里指定了Route的outlet,注意就和main.component.html里面的对应起来了。
active-menu.directive.ts
定义了jhiActiveMenu属性指令,用来作为激活语种的辅助指令。默认菜单的激活状态是routerLinkActive根据url进行判断的,但是语种的选择与激活是与url无关的,因此必须自己判断那一个语种是激活的。
核心代码为updateActivFlag()方法
updateActiveFlag(selectedLanguage) {
if (this.jhiActiveMenu === selectedLanguage) {
this.renderer.setElementClass(this.el.nativeElement, 'active', true);
} else {
this.renderer.setElementClass(this.el.nativeElement, 'active', false);
}
}
就是给属性的标签元素上增加或者删除'active'属性。
navbar.component组件
NavbarComponent不仅仅展示菜单外观,还包含不需要路由转换的一些动作语言转换的动作。登录,登出,语种切换。
navbar.component.html就是一个相当标准的ngbMenu的html文件了。如果窗口768px,菜单就会自动折叠。
<!-- 整个组件用nav标签包起来。-->
<nav class="navbar navbar-dark navbar-expand-md jh-navbar">
<div class="jh-logo-container float-left">
<!--这块是折叠时候的fa-bars图标,仅当折叠时候显示-->
<a class="jh-navbar-toggler d-lg-none float-right" href="javascript:void(0);" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation" (click)="toggleNavbar()">
<i class="fa fa-bars"></i>
</a>
<!--左边一块显示Jhipster图标,工程名,版本信息。-->
<a class="navbar-brand logo float-left" routerLink="/" (click)="collapseNavbar()">
<span class="logo-img"></span>
<span jhiTranslate="global.title" class="navbar-title">JhipsterSampleApplicationNG2</span> <span class="navbar-version">{{version}}</span>
</a>
</div>
<!--这里开始是menu的区域,使用ngbCollapse控制折叠状态,navbarResponsive的id为data-target-->
<!--这了用ngSwitch判断登录情况(所以打开首页,也会自动触发/api/account通讯API -->
<div class="navbar-collapse collapse" id="navbarResponsive" [ngbCollapse]="isNavbarCollapsed" [ngSwitch]="isAuthenticated()">
<ul class="navbar-nav ml-auto">
<!--第一个菜单项-home-->
<li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
<a class="nav-link" routerLink="/" (click)="collapseNavbar()">
<span>
<i class="fa fa-home" aria-hidden="true"></i>
<span jhiTranslate="global.menu.home">Home</span>
</span>
</a>
</li>
<!-- jhipster-needle-add-element-to-menu - JHipster will add new menu items here -->
<!-- Entities子菜单由jhipster管理,会根据cli自动修改该部分内容 ,该菜单仅当用户登录后显示-->
<li *ngSwitchCase="true" ngbDropdown class="nav-item dropdown pointer" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
<a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="entity-menu">
<span>
<i class="fa fa-th-list" aria-hidden="true"></i>
<span jhiTranslate="global.menu.entities.main">
Entities
</span>
</span>
</a>
<!-- 子菜单dropdown下拉框 -->
<ul class="dropdown-menu" ngbDropdownMenu>
<li>
<a class="dropdown-item" routerLink="bank-account" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }" (click)="collapseNavbar()">
<i class="fa fa-fw fa-asterisk" aria-hidden="true"></i>
<span jhiTranslate="global.menu.entities.bankAccount">Bank Account</span>
</a>
</li>
<!-- 其他实体,略过 -->
<!-- jhipster-needle-add-entity-to-menu - JHipster will add entities to the menu here -->
</ul>
</li>
<!-- Administration子菜单,该菜单使用了jhiHasAnyAuthority指令,需要有ROLE_ADMIN才显示 -->
<li *jhiHasAnyAuthority="'ROLE_ADMIN'" ngbDropdown class="nav-item dropdown pointer" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
<a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="admin-menu">
<span>
<i class="fa fa-user-plus" aria-hidden="true"></i>
<span jhiTranslate="global.menu.admin.main">Administration</span>
</span>
</a>
<!-- 子菜单dropdown下拉框 -->
<ul class="dropdown-menu" ngbDropdownMenu>
<li>
<a class="dropdown-item" routerLink="user-management" routerLinkActive="active" (click)="collapseNavbar()">
<i class="fa fa-fw fa-user" aria-hidden="true"></i>
<span jhiTranslate="global.menu.admin.userManagement">User management</span>
</a>
</li>
<!-- 省略-->
<!-- swagger菜单,会根据后台返回的profile显示与否 -->
<li *ngIf="swaggerEnabled">
<a class="dropdown-item" routerLink="docs" routerLinkActive="active" (click)="collapseNavbar()">
<i class="fa fa-fw fa-book" aria-hidden="true"></i>
<span jhiTranslate="global.menu.admin.apidocs">API</span>
</a>
</li>
<!-- jhipster-needle-add-element-to-admin-menu - JHipster will add entities to the admin menu here -->
<!-- 非生产Profile,增加连接H2数据库的菜单,如果不用H2,这个就可以隐藏掉 -->
<li *ngIf="!inProduction">
<a class="dropdown-item" href='./h2-console' target="_tab" (click)="collapseNavbar()">
<i class="fa fa-fw fa-hdd-o" aria-hidden="true"></i>
<span jhiTranslate="global.menu.admin.database">Database</span>
</a>
</li>
</ul>
</li>
<!--语种子菜单-仅当languages为真,多于一个语种时候才显示 -->
<li ngbDropdown class="nav-item dropdown pointer" *ngIf="languages">
<a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="languagesnavBarDropdown" *ngIf="languages.length > 1">
<span>
<i class="fa fa-flag" aria-hidden="true"></i>
<span jhiTranslate="global.menu.language">Language</span>
</span>
</a>
<ul class="dropdown-menu" ngbDropdownMenu *ngIf="languages.length > 1">
<!-- 用ngfor 显示语种列表,并用上jhiActiveMenu判断语种激活情况,这里还是用了findLanguageFromKey显示语种的全称 -->
<li *ngFor="let language of languages">
<a class="dropdown-item" [jhiActiveMenu]="language" href="javascript:void(0);" (click)="changeLanguage(language);collapseNavbar();">{{language | findLanguageFromKey}}</a>
</li>
</ul>
</li>
<!--Account子菜单-->
<li ngbDropdown class="nav-item dropdown pointer" placement="bottom-right" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
<a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="account-menu">
<span *ngIf="!getImageUrl()">
<i class="fa fa-user" aria-hidden="true"></i>
<span jhiTranslate="global.menu.account.main">
Account
</span>
</span>
<!--如果能获取用头像,就在这里显示-->
<span *ngIf="getImageUrl()">
<img [src]="getImageUrl()" class="profile-image img-circle" alt="Avatar">
</span>
</a>
<!-- 子菜单dropdown下拉框 -->
<ul class="dropdown-menu" ngbDropdownMenu>
<!--Settings仅当用户登录情况才显示-->
<li *ngSwitchCase="true">
<a class="dropdown-item" routerLink="settings" routerLinkActive="active" (click)="collapseNavbar()">
<i class="fa fa-fw fa-wrench" aria-hidden="true"></i>
<span jhiTranslate="global.menu.account.settings">Settings</span>
</a>
</li>
<!--省略部分菜单-->
</ul>
</li>
</ul>
</div>
</nav>