在呈现Bootstrap模式之前重置Angular 2/4中的变量
因此,我注意到我的引导模式与Angular 4结合时出现了一种非常奇怪的效果,其中先前打开的图像在从我的图库加载新选择的图像之前首先弹出。原因是我的值的详细信息变量仍然使用之前(单击)事件的旧值填充。我可以在我的控制台日志中验证这一点。我的问题是如何在给它一个新值之前,在我的getArtworkDetail()方法中重置这个变量?在呈现Bootstrap模式之前重置Angular 2/4中的变量
我尝试设置它像
this.details = undefined;
或
this.details = null;
,但它似乎简化版,登记在所有的价值,而是阻止模式加载。我的同事说这是由于TypeScript的单线程性质,但是我对这个主题的研究很短,所以我希望在这里得到一些帮助。多谢!
index.component.html
<!--SEARCH-->
<div class="input-group">
<input #myInput
[(ngModel)]="searchTerm"
type="text"
class="form-control"
placeholder="Search artist or artwork..."
(keyup.enter)="search()"/>
<span class="input-group-btn">
<button #myBtn
(click)="search()"
class="btn btn-default"
type="button">Go!
</button>
</span>
</div>
<!--INDEX-->
<div class="row"
*ngIf="hasArtPieces">
<div *ngFor="let artwork of artworks"
class="col-md-3 col-xs-12 centered">
<div class="card">
<a (click)="getArtworkDetail(artwork.id)"
data-toggle="modal"
data-target="#myModal">
<img class="img-fluid thumb-img"
src="{{artwork.url}}"
alt="Thumbnail">
</a>
<div class="card-block">
<p style="text-align: center"
*ngIf="artwork.title.length < 20; then show else hide">
</p>
<ng-template #show>{{artwork.title }}</ng-template>
<ng-template #hide>{{artwork.title.substring(0,20)}}...</ng-template>
</div>
</div>
<br>
</div>
</div>
<!--DETAIL-->
<div *ngIf="details"
class="modal fade"
id="myModal" tabindex="-1"
role="dialog"
aria-labelledby="myModalLabel">
<div class="modal-dialog"
role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button"
class="close"
data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<h1>{{details.title}}</h1>
<h3>{{details.artist}}</h3>
<img class="img-fluid" src="{{details.url}}"
alt=""><br><br>
<p>{{details.description}}</p>
</div>
<div class="modal-footer">
<button type="button"
class="btn btn-default"
data-dismiss="modal">Close
</button>
</div>
</div>
</div>
</div>
index.component.ts
// imports emitted
@Component({
selector: 'artwork-index',
templateUrl: './index.component.html',
styleUrls: ['./index.component.css']
})
export class IndexComponent implements OnInit {
artworks: ArtworkModel[];
searchTerm: string;
details: ArtworkDetailModel;
hasArtPieces = false;
constructor(private detailService: ArtworkDetailsService, private artworksService: ArtworksService) {
}
search() {
if (this.searchTerm) {
this.searchArtworks(this.searchTerm);
}
}
searchArtworks(keyword) {
this.artworksService.searchArtworks(keyword)
.subscribe((artworkData: ArtworkModel[]) => {
this.artworks = artworkData;
this.hasArtPieces = true;
}, err => console.log(err),
() => console.log('Getting artworks complete...'));
}
getArtworkDetail(id) {
this.detailService.getArtworkDetail(id)
.subscribe((detailData: ArtworkDetailModel) => {
this.details = detailData;
}, err => console.log(err),
() => console.log('Getting details complete...'));
}
ngOnInit() {
this.searchArtworks('Rembrandt');
}
}
这似乎是发生了你的是,data-toggle="modal"
锚元素((click)="getArtworkDetail(artwork.id)"
)触发器请求作品细节前的模式已完成。
尝试这两个东西:
- 从模态DIV取出
*ngIf="details"
指令。相反,将*ngIf="details"
放在内部元素上 - 可能是.modal-body
元素或该元素内部的容器div。- 这将允许缩略图按钮,触发模态,而不必等待艺术品细节加载
- 添加
this.details = null;
回getArtworkDetail
作为函数的第一行。随着新的详细信息正在加载,这将清除所有旧的详细信息。
您可能希望显示一个微调框,直到该请求在某个点完成为止。在这种情况下,您可以使用*ngIf="details"
指令提供微调,而details
值为空:*ngIf="details; else spinner"
。
单线程的性质,你的同事称实际上是关于JavaScript的,而不是打字稿,因为打字稿被执行之前编译为JavaScript。 JavaScript有效地作为单线程事件循环运行(尽管这不是guaranteed),但是由这些事件触发的某些任务可能会异步发生。一个这样的异步任务是XMLHttpRequest。由于这是异步发生的,因此脚本无需等待它完成,然后再尝试显示模态,这是您的问题所在。
As Mike Hill pointed out 的解决方案是将*ngIf
添加到内部元件,并设置我的this.details = null
,没有工作,但this.details = undefined
工作,因此结束了与*ngif
上modal-body
看起来像这样:
指数.component.html
...
<!--DETAIL-->
<div
class="modal fade"
id="myModal" tabindex="-1"
role="dialog"
aria-labelledby="myModalLabel">
<div class="modal-dialog"
role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button"
class="close"
data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body"
*ngIf="details">
<h1>{{details.title}}</h1>
<h3>{{details.artist}}</h3>
<img class="img-fluid" src="{{details.url}}"
alt=""><br><br>
<p>{{details.description}}</p>
</div>
<div class="modal-footer">
<button type="button"
class="btn btn-default"
data-dismiss="modal">Close
</button>
</div>
</div>
</div>
</div>
index.component.ts
...
getArtworkDetail(id) {
this.details = undefined;
this.detailService.getArtworkDetail(id)
.subscribe((detailData: ArtworkDetailModel) => {
this.details = detailData;
}, err => console.log(err),
() => console.log('Getting details complete...'));
}
谢谢!这解决了我的问题:) –