如何在 Angular4 中为多个项目显示带有 *ngFor 的模态 window
How to show a modal window with *ngFor for multiple items in Angular4
我正在尝试一个简单的项目来学习 Angular,但我目前遇到了一个问题:
我正在为一些虚拟人加载服务,然后显示带有这些人姓名的框。当我单击一个框时,会出现一个模式弹出窗口并显示有关此人的更多信息 - 目前只是 string
的简短简历。
问题是我有一个 *ngFor
迭代 persons
然后我怀疑发生的是我还为每个人创建了一个模态 window。然后模态 window 不知道当前选择的人是谁,所以它只显示列表中第一个人的简历 ...
所以问题是我如何让它适用于每个当前选定的人;即当我点击 id = 3 的人时,模态显示同一个人的简历。
我想这需要以编程方式完成,这就是为什么我不使用 href="#modal" data-toggle="modal"
之类的东西将模式 window 绑定到事件的原因。
有什么更好的主意吗?
这是我的:PersonComponent
@Component({
selector: 'person',
templateUrl: './person.component.html'
})
export class PersonComponent implements OnInit {
people: Person[];
selectedPerson: Person;
personBio: string;
@ViewChild('personModal') private personModal;
constructor(private router: Router,
private activatedRoute: ActivatedRoute,
private stateService: StateService,
private personService: PersonService) {
}
ngOnInit() {
this.loadAllPeople();
}
private loadAllPeople() {
this.personService.getPeople()
.subscribe(result => {
this.people = result;
}, error => {
this.console.log(error);
});
}
goToPersonEditComponent(person: Person) {
this.stateService.person = this.selectedPerson;
this.router.navigate(['../' + FrontendRoute.EDIT], {relativeTo: this.activatedRoute});
}
loadPersonBioModal(person: Person) {
if (this.personModal) {
this.selectedPerson = person;
jQuery(this.personModal.nativeElement).modal('show');
}
this.personService.getPersonBio(person.id)
.subscribe((bio) => this.personBio = bio);
}
closeModal() {
if (this.personModal) {
jQuery(this.personModal.nativeElement).on('hide.bs.modal', (evt) => {
this.selectedPerson = null;
});
}
}
}
人物编辑组件:为了简单起见,我没有展示整个内容,但我的想法是我得到了选定的人物,我可以从 id 属性编辑它的个人简介。
@Component({
selector: 'person-edit',
templateUrl: './person-edit.component.html'
})
export class PersonEditComponent implements OnInit {
person: Person;
constructor(private router: Router,
private activatedRoute: ActivatedRoute,
private packService: PackService,
private orderService: PackOrderService,
private stateService: StateService,
private eventBusService: EventBusService,
private loggingService: LoggingService) {
}
ngOnInit() {
this.person = this.stateService.person;
}
}
用于在组件之间传递内容的简单服务(我想要这种方式而不是使用@Input):
@Injectable()
export class StateService {
private _person: Person;
constructor() {
}
get person() {
return this._person;
}
set person(person: Person) {
this._person = person;
}
clear() {
this._person = null;
}
}
这是我的模板,其中有 modal
:
<div>
<h2 class="h2">People</h2>
<div class="item-collection item-collection-3-columns item-collection-tablet item-collection-wide">
<div class="items">
<article *ngFor="let person of people"
(click)="loadPersonBioModal(person)">
<div class="content">
<div class="headline">
<span>{{person.name}}</span>
<span data-original-title="Show Person's Bio"></span>
</div>
</div>
</article>
</div>
</div>
</div>
<div #personModal tabindex="-1" role="dialog" class="modal fade" style="display: none;"
aria-hidden="true">
<div role="document" class="modal-dialog modal-lg modal-has-header modal-has-footer">
<div class="modal-content">{{personBio}}</div>
<div class="modal-footer">
<div class="section-btns">
<button type="button" data-dismiss="modal"
(click)="closeModal()">Close
</button>
<button type="button" data-dismiss="modal"
(click)="goToPersonEditComponent(selectedPerson)">Edit Bio
</button>
</div>
</div>
</div>
</div>
这里是进行 http 调用的 PersonService:
@Injectable()
export class PersonService {
constructor(private http: HttpClient, private router: Router) {
}
getPeople(): Observable<Person[]> {
return this.http.get<Person[]>(BackendRoute.PERSON_DATA)
.catch(error => {
return Observable.throw(new Error('An unexpected error occurred' + error));
});
}
getPersonBio(): Observable<Person> {
return this.http.get<Person>(BackendRoute.PERSON_BIO)
.catch(error => Observable.throw(new Error(error)));
});
}
}
好的,根据您的意见,我认为可能发生的情况是您在 getPersonBio()
returns 人员信息之前显示您的模态并将其分配给 personBio
属性.
解决这个问题的一个可能简单的方法是使用 async 管道为您异步更新值。试试这个,
在你的 PersonComponent 中,
personBio: Observable<Person>;
loadPersonBioModal(person: Person) {
if (this.personModal) {
this.selectedPerson = person;
// directly assigning the returned observable of Person type and let async pipe do its magic in the template
this.personBio = this.personService.getPersonBio(person.id);
jQuery(this.personModal.nativeElement).modal('show');
}
}
在您的模板中,
<div class="modal-content">{{ personBio | async }}</div>
您必须导入 CommonModule
才能正常工作,正如 docs 中可能看到的那样。此外,不建议直接在 angular 中使用 jQuery 方法,除非没有其他支持的方法。
如果有帮助请告诉我。
我正在尝试一个简单的项目来学习 Angular,但我目前遇到了一个问题:
我正在为一些虚拟人加载服务,然后显示带有这些人姓名的框。当我单击一个框时,会出现一个模式弹出窗口并显示有关此人的更多信息 - 目前只是 string
的简短简历。
问题是我有一个 *ngFor
迭代 persons
然后我怀疑发生的是我还为每个人创建了一个模态 window。然后模态 window 不知道当前选择的人是谁,所以它只显示列表中第一个人的简历 ...
所以问题是我如何让它适用于每个当前选定的人;即当我点击 id = 3 的人时,模态显示同一个人的简历。
我想这需要以编程方式完成,这就是为什么我不使用 href="#modal" data-toggle="modal"
之类的东西将模式 window 绑定到事件的原因。
有什么更好的主意吗?
这是我的:PersonComponent
@Component({
selector: 'person',
templateUrl: './person.component.html'
})
export class PersonComponent implements OnInit {
people: Person[];
selectedPerson: Person;
personBio: string;
@ViewChild('personModal') private personModal;
constructor(private router: Router,
private activatedRoute: ActivatedRoute,
private stateService: StateService,
private personService: PersonService) {
}
ngOnInit() {
this.loadAllPeople();
}
private loadAllPeople() {
this.personService.getPeople()
.subscribe(result => {
this.people = result;
}, error => {
this.console.log(error);
});
}
goToPersonEditComponent(person: Person) {
this.stateService.person = this.selectedPerson;
this.router.navigate(['../' + FrontendRoute.EDIT], {relativeTo: this.activatedRoute});
}
loadPersonBioModal(person: Person) {
if (this.personModal) {
this.selectedPerson = person;
jQuery(this.personModal.nativeElement).modal('show');
}
this.personService.getPersonBio(person.id)
.subscribe((bio) => this.personBio = bio);
}
closeModal() {
if (this.personModal) {
jQuery(this.personModal.nativeElement).on('hide.bs.modal', (evt) => {
this.selectedPerson = null;
});
}
}
}
人物编辑组件:为了简单起见,我没有展示整个内容,但我的想法是我得到了选定的人物,我可以从 id 属性编辑它的个人简介。
@Component({
selector: 'person-edit',
templateUrl: './person-edit.component.html'
})
export class PersonEditComponent implements OnInit {
person: Person;
constructor(private router: Router,
private activatedRoute: ActivatedRoute,
private packService: PackService,
private orderService: PackOrderService,
private stateService: StateService,
private eventBusService: EventBusService,
private loggingService: LoggingService) {
}
ngOnInit() {
this.person = this.stateService.person;
}
}
用于在组件之间传递内容的简单服务(我想要这种方式而不是使用@Input):
@Injectable()
export class StateService {
private _person: Person;
constructor() {
}
get person() {
return this._person;
}
set person(person: Person) {
this._person = person;
}
clear() {
this._person = null;
}
}
这是我的模板,其中有 modal
:
<div>
<h2 class="h2">People</h2>
<div class="item-collection item-collection-3-columns item-collection-tablet item-collection-wide">
<div class="items">
<article *ngFor="let person of people"
(click)="loadPersonBioModal(person)">
<div class="content">
<div class="headline">
<span>{{person.name}}</span>
<span data-original-title="Show Person's Bio"></span>
</div>
</div>
</article>
</div>
</div>
</div>
<div #personModal tabindex="-1" role="dialog" class="modal fade" style="display: none;"
aria-hidden="true">
<div role="document" class="modal-dialog modal-lg modal-has-header modal-has-footer">
<div class="modal-content">{{personBio}}</div>
<div class="modal-footer">
<div class="section-btns">
<button type="button" data-dismiss="modal"
(click)="closeModal()">Close
</button>
<button type="button" data-dismiss="modal"
(click)="goToPersonEditComponent(selectedPerson)">Edit Bio
</button>
</div>
</div>
</div>
</div>
这里是进行 http 调用的 PersonService:
@Injectable()
export class PersonService {
constructor(private http: HttpClient, private router: Router) {
}
getPeople(): Observable<Person[]> {
return this.http.get<Person[]>(BackendRoute.PERSON_DATA)
.catch(error => {
return Observable.throw(new Error('An unexpected error occurred' + error));
});
}
getPersonBio(): Observable<Person> {
return this.http.get<Person>(BackendRoute.PERSON_BIO)
.catch(error => Observable.throw(new Error(error)));
});
}
}
好的,根据您的意见,我认为可能发生的情况是您在 getPersonBio()
returns 人员信息之前显示您的模态并将其分配给 personBio
属性.
解决这个问题的一个可能简单的方法是使用 async 管道为您异步更新值。试试这个,
在你的 PersonComponent 中,
personBio: Observable<Person>;
loadPersonBioModal(person: Person) {
if (this.personModal) {
this.selectedPerson = person;
// directly assigning the returned observable of Person type and let async pipe do its magic in the template
this.personBio = this.personService.getPersonBio(person.id);
jQuery(this.personModal.nativeElement).modal('show');
}
}
在您的模板中,
<div class="modal-content">{{ personBio | async }}</div>
您必须导入 CommonModule
才能正常工作,正如 docs 中可能看到的那样。此外,不建议直接在 angular 中使用 jQuery 方法,除非没有其他支持的方法。
如果有帮助请告诉我。