Bootstrap angular 按钮组中的响应问题
Bootstrap angular responsivity issue in button group
我是前端开发的新手,我希望成为全栈,我正在使用 Jhipster,angular 和 bootstrap 用于自学目的。
我成功安装了一个 bootswatch 主题(pulse),经过一些工作我尝试创建一个卡片列表来展示一些数据。
不幸的是,我的作品在平板电脑模式下缺乏响应性,如下图所示
如你所见,有很多事情要做,我不知道我应该怎么做才能解决所有问题
所以我 一开始只询问如何解决我的卡片中的按钮问题,也许这会让我理解并掌握独自做什么其他问题(菜单和过滤器)
下面我提供了我认为暗示的所有代码:
主应用模板
<jhi-page-ribbon></jhi-page-ribbon>
<div>
<router-outlet name="navbar"></router-outlet>
</div>
<div class="container-fluid">
<div class="container-fluid mt-4">
<router-outlet></router-outlet>
<router-outlet name="popup"></router-outlet>
</div>
<jhi-footer></jhi-footer>
</div>
我的候选模板中的卡片代码片段
1 全局模板:所有代码
<div>
<h2 id="page-heading">
<span jhiTranslate="autoEcoleV01App.candidat.home.title">Candidats</span>
<button id="jh-create-entity" class="btn btn-primary float-right jh-create-entity create-candidat"
[routerLink]="['/candidat/new']">
<fa-icon [icon]="'plus'"></fa-icon>
<span jhiTranslate="autoEcoleV01App.candidat.home.createLabel">
Create new Candidat
</span>
</button>
</h2>
<jhi-alert></jhi-alert>
<br />
<div jhiSort [(predicate)]="predicate" [(ascending)]="reverse" [callback]="transition.bind(this)">
<div class="row mb-4 ml-1">
<input type="search" class="form-control col-sm-8 " autocomplete="off" placeholder="{{'autoEcoleV01App.constants.search' | translate}}"
[(ngModel)]="searchValue" />
<div class="btn-group col-sm-4">
<button class="btn btn-sm float-left btn-outline-secondary col" jhiSortBy="nom">
<span jhiTranslate="autoEcoleV01App.candidat.nom">Nom</span>
<fa-icon [icon]="'sort'"></fa-icon>
</button>
<button class="btn btn-sm float-left btn-outline-secondary col" jhiSortBy="prenom">
<span jhiTranslate="autoEcoleV01App.candidat.prenom">Prenom</span>
<fa-icon [icon]="'sort'"></fa-icon>
</button>
<button class="btn btn-sm float-left btn-outline-secondary col" jhiSortBy="nid">
<span jhiTranslate="autoEcoleV01App.candidat.nid">Nid</span>
<fa-icon [icon]="'sort'"></fa-icon>
</button>
</div>
</div>
<div class="row">
<div *ngFor="let candidat of (candidats | filterBy: ['nom','prenom','mere','pere','telephone','nid']: searchValue) ;trackBy: trackId"
class="col-sm-3 mb-4">
<div class="card card-focusable" style="min-height: 100%;">
<a *ngIf="candidat.photo" (click)="openFile(candidat.photoContentType, candidat.photo)">
<img [src]="'data:' + candidat.photoContentType + ';base64,' + candidat.photo"
style="max-height: 360px; max-width: 100%;"
class="card-img-top " alt="candidat image" />
</a>
<div class="card-body ">
<h4 class="card-title">{{candidat.nom}} {{candidat.prenom}}</h4>
<p class="card-text ml-1">
<span jhiTranslate="autoEcoleV01App.candidat.dateInscription">Date Inscription </span>: {{candidat.dateInscription | date:'mediumDate'}}
<br >
<span jhiTranslate="autoEcoleV01App.candidat.telephone">Téléphone </span>: {{candidat.telephone}}
</p>
<div class="text-right">
<div class="btn-group flex-btn-group-container">
<button type="submit" [routerLink]="['/candidat', candidat.id, 'view' ]"
class="btn btn-info btn-sm">
<fa-icon [icon]="'eye'"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.view">View</span>
</button>
<button type="submit" [routerLink]="['/candidat', candidat.id, 'edit']"
class="btn btn-primary btn-sm">
<fa-icon [icon]="'pencil-alt'"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.edit">Edit</span>
</button>
<button type="submit"
[routerLink]="['/', 'candidat', { outlets: { popup: candidat.id + '/delete'} }]"
replaceUrl="true" queryParamsHandling="merge" class="btn btn-danger btn-sm">
<fa-icon [icon]="'times'"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.delete">Delete</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
2 只有卡码方便阅读
<div class="card-body ">
<h4 class="card-title">{{candidat.nom}} {{candidat.prenom}}</h4>
<p class="card-text ml-1">
<span jhiTranslate="autoEcoleV01App.candidat.dateInscription">Date Inscription </span>: {{candidat.dateInscription | date:'mediumDate'}}
<br >
<span jhiTranslate="autoEcoleV01App.candidat.telephone">Téléphone </span>: {{candidat.telephone}}
</p>
<div class="text-right">
<div class="btn-group flex-btn-group-container">
<button type="submit" [routerLink]="['/candidat', candidat.id, 'view' ]"
class="btn btn-info btn-sm">
<fa-icon [icon]="'eye'"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.view">View</span>
</button>
<button type="submit" [routerLink]="['/candidat', candidat.id, 'edit']"
class="btn btn-primary btn-sm">
<fa-icon [icon]="'pencil-alt'"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.edit">Edit</span>
</button>
<button type="submit"
[routerLink]="['/', 'candidat', { outlets: { popup: candidat.id + '/delete'} }]"
replaceUrl="true" queryParamsHandling="merge" class="btn btn-danger btn-sm">
<fa-icon [icon]="'times'"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.delete">Delete</span>
</button>
</div>
</div>
</div>
感谢 JB Nizet 的评论,我走上了正路,所以我寻找了一种方法来确保有足够的 space,我的答案是 Breakpoints
这是我所做的:
- 我用了angular material and this tutorial was helpfull
- 设定一个目标:我必须根据屏幕尺寸更改卡片数量
这是我的解决方案实现
正在我的全局应用程序模块中导入模块app.module.ts
以在所有组件中使用
import { LayoutModule } from '@angular/cdk/layout';
@NgModule({
imports: [...
LayoutModule,
...])
在我的 candidat.component.ts
中使用 BreakpointService
import { BreakpointObserver, BreakpointState, Breakpoints } from '@angular/cdk/layout';
@Component({
selector: 'jhi-candidat',
templateUrl: './candidat.component.html'
})
export class CandidatComponent implements OnInit, OnDestroy {
someVars: any;
small: any;
medium: any;
large: any;
constructor(
protected someServices: MyServices,
public breakpointObserver: BreakpointObserver
){}
ngOnInit() {
this.someLogic();
this.breakpointObserver
.observe(['(max-width: 425px)'])
.subscribe((state: BreakpointState) => {
if (state.matches) {
this.small = true;
this.medium = false;
this.large = false;
}
console.log('Small screen event');
});
this.breakpointObserver
.observe(['(max-width: 1025px)', '(min-width: 426px)'])
.subscribe((state: BreakpointState) => {
if (state.matches) {
this.small = false;
this.medium = true;
this.large = false;
}
console.log('Medium screen event');
});
this.breakpointObserver
.observe(['(min-width: 1025px)'])
.subscribe((state: BreakpointState) => {
if (state.matches) {
this.small = false;
this.medium = false;
this.large = true;
}
console.log('Large screen event');
});
}
cardsStyleClasses() {
return {
'mb-4': true,
'col-sm-1': this.small,
'col-sm-4': this.medium,
'col-sm-3': this.large
};
}
}
终于在我的模板中使用 ngClass
[ngClass]="cardsStyleClasses()"
我是前端开发的新手,我希望成为全栈,我正在使用 Jhipster,angular 和 bootstrap 用于自学目的。
我成功安装了一个 bootswatch 主题(pulse),经过一些工作我尝试创建一个卡片列表来展示一些数据。
不幸的是,我的作品在平板电脑模式下缺乏响应性,如下图所示
如你所见,有很多事情要做,我不知道我应该怎么做才能解决所有问题
所以我 一开始只询问如何解决我的卡片中的按钮问题,也许这会让我理解并掌握独自做什么其他问题(菜单和过滤器)
下面我提供了我认为暗示的所有代码:
主应用模板
<jhi-page-ribbon></jhi-page-ribbon>
<div>
<router-outlet name="navbar"></router-outlet>
</div>
<div class="container-fluid">
<div class="container-fluid mt-4">
<router-outlet></router-outlet>
<router-outlet name="popup"></router-outlet>
</div>
<jhi-footer></jhi-footer>
</div>
我的候选模板中的卡片代码片段
1 全局模板:所有代码
<div>
<h2 id="page-heading">
<span jhiTranslate="autoEcoleV01App.candidat.home.title">Candidats</span>
<button id="jh-create-entity" class="btn btn-primary float-right jh-create-entity create-candidat"
[routerLink]="['/candidat/new']">
<fa-icon [icon]="'plus'"></fa-icon>
<span jhiTranslate="autoEcoleV01App.candidat.home.createLabel">
Create new Candidat
</span>
</button>
</h2>
<jhi-alert></jhi-alert>
<br />
<div jhiSort [(predicate)]="predicate" [(ascending)]="reverse" [callback]="transition.bind(this)">
<div class="row mb-4 ml-1">
<input type="search" class="form-control col-sm-8 " autocomplete="off" placeholder="{{'autoEcoleV01App.constants.search' | translate}}"
[(ngModel)]="searchValue" />
<div class="btn-group col-sm-4">
<button class="btn btn-sm float-left btn-outline-secondary col" jhiSortBy="nom">
<span jhiTranslate="autoEcoleV01App.candidat.nom">Nom</span>
<fa-icon [icon]="'sort'"></fa-icon>
</button>
<button class="btn btn-sm float-left btn-outline-secondary col" jhiSortBy="prenom">
<span jhiTranslate="autoEcoleV01App.candidat.prenom">Prenom</span>
<fa-icon [icon]="'sort'"></fa-icon>
</button>
<button class="btn btn-sm float-left btn-outline-secondary col" jhiSortBy="nid">
<span jhiTranslate="autoEcoleV01App.candidat.nid">Nid</span>
<fa-icon [icon]="'sort'"></fa-icon>
</button>
</div>
</div>
<div class="row">
<div *ngFor="let candidat of (candidats | filterBy: ['nom','prenom','mere','pere','telephone','nid']: searchValue) ;trackBy: trackId"
class="col-sm-3 mb-4">
<div class="card card-focusable" style="min-height: 100%;">
<a *ngIf="candidat.photo" (click)="openFile(candidat.photoContentType, candidat.photo)">
<img [src]="'data:' + candidat.photoContentType + ';base64,' + candidat.photo"
style="max-height: 360px; max-width: 100%;"
class="card-img-top " alt="candidat image" />
</a>
<div class="card-body ">
<h4 class="card-title">{{candidat.nom}} {{candidat.prenom}}</h4>
<p class="card-text ml-1">
<span jhiTranslate="autoEcoleV01App.candidat.dateInscription">Date Inscription </span>: {{candidat.dateInscription | date:'mediumDate'}}
<br >
<span jhiTranslate="autoEcoleV01App.candidat.telephone">Téléphone </span>: {{candidat.telephone}}
</p>
<div class="text-right">
<div class="btn-group flex-btn-group-container">
<button type="submit" [routerLink]="['/candidat', candidat.id, 'view' ]"
class="btn btn-info btn-sm">
<fa-icon [icon]="'eye'"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.view">View</span>
</button>
<button type="submit" [routerLink]="['/candidat', candidat.id, 'edit']"
class="btn btn-primary btn-sm">
<fa-icon [icon]="'pencil-alt'"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.edit">Edit</span>
</button>
<button type="submit"
[routerLink]="['/', 'candidat', { outlets: { popup: candidat.id + '/delete'} }]"
replaceUrl="true" queryParamsHandling="merge" class="btn btn-danger btn-sm">
<fa-icon [icon]="'times'"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.delete">Delete</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
2 只有卡码方便阅读
<div class="card-body ">
<h4 class="card-title">{{candidat.nom}} {{candidat.prenom}}</h4>
<p class="card-text ml-1">
<span jhiTranslate="autoEcoleV01App.candidat.dateInscription">Date Inscription </span>: {{candidat.dateInscription | date:'mediumDate'}}
<br >
<span jhiTranslate="autoEcoleV01App.candidat.telephone">Téléphone </span>: {{candidat.telephone}}
</p>
<div class="text-right">
<div class="btn-group flex-btn-group-container">
<button type="submit" [routerLink]="['/candidat', candidat.id, 'view' ]"
class="btn btn-info btn-sm">
<fa-icon [icon]="'eye'"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.view">View</span>
</button>
<button type="submit" [routerLink]="['/candidat', candidat.id, 'edit']"
class="btn btn-primary btn-sm">
<fa-icon [icon]="'pencil-alt'"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.edit">Edit</span>
</button>
<button type="submit"
[routerLink]="['/', 'candidat', { outlets: { popup: candidat.id + '/delete'} }]"
replaceUrl="true" queryParamsHandling="merge" class="btn btn-danger btn-sm">
<fa-icon [icon]="'times'"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.delete">Delete</span>
</button>
</div>
</div>
</div>
感谢 JB Nizet 的评论,我走上了正路,所以我寻找了一种方法来确保有足够的 space,我的答案是 Breakpoints
这是我所做的:
- 我用了angular material and this tutorial was helpfull
- 设定一个目标:我必须根据屏幕尺寸更改卡片数量
这是我的解决方案实现
正在我的全局应用程序模块中导入模块app.module.ts
以在所有组件中使用
import { LayoutModule } from '@angular/cdk/layout';
@NgModule({
imports: [...
LayoutModule,
...])
在我的 candidat.component.ts
BreakpointService
import { BreakpointObserver, BreakpointState, Breakpoints } from '@angular/cdk/layout';
@Component({
selector: 'jhi-candidat',
templateUrl: './candidat.component.html'
})
export class CandidatComponent implements OnInit, OnDestroy {
someVars: any;
small: any;
medium: any;
large: any;
constructor(
protected someServices: MyServices,
public breakpointObserver: BreakpointObserver
){}
ngOnInit() {
this.someLogic();
this.breakpointObserver
.observe(['(max-width: 425px)'])
.subscribe((state: BreakpointState) => {
if (state.matches) {
this.small = true;
this.medium = false;
this.large = false;
}
console.log('Small screen event');
});
this.breakpointObserver
.observe(['(max-width: 1025px)', '(min-width: 426px)'])
.subscribe((state: BreakpointState) => {
if (state.matches) {
this.small = false;
this.medium = true;
this.large = false;
}
console.log('Medium screen event');
});
this.breakpointObserver
.observe(['(min-width: 1025px)'])
.subscribe((state: BreakpointState) => {
if (state.matches) {
this.small = false;
this.medium = false;
this.large = true;
}
console.log('Large screen event');
});
}
cardsStyleClasses() {
return {
'mb-4': true,
'col-sm-1': this.small,
'col-sm-4': this.medium,
'col-sm-3': this.large
};
}
}
终于在我的模板中使用 ngClass
[ngClass]="cardsStyleClasses()"