1

그래서 내 갤러리에서 새로 선택한 이미지를로드하기 전에 이전에 열었던 이미지가 처음 나타나는 팝업 4와 결합 된 부트 스트랩 모달에 상당히 이상한 효과가 나타났습니다. 그 이유는 내 세부 사항 변수가 이전 (클릭) 이벤트의 이전 값으로 채워지 기 때문입니다. 내 콘솔 로그에서이를 확인할 수 있습니다. 내 질문에 내 변수를 새 값으로 제공하기 전에 내 getArtworkDetail() 메서드에서이 변수를 어떻게 재설정합니까? 렌더링하기 전에 각도 2/4로 변수 재설정하기 부트 스트랩 모달

나는

this.details = undefined; 

또는

this.details = null; 

처럼 설정을 시도했지만 모두에서 값을 등록하는 것 does't 대신로드에서 모달을 방지 할 수 있습니다. 제 동료는 이것이 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">&times;</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'); 
    } 
} 

답변

2

그 트리거 ((click)="getArtworkDetail(artwork.id)" 포함) data-toggle="modal" 앵커 요소 작품 세부 사항 요청이 완료되기 전에 모달.

는이 두 가지를 시도해보십시오

  1. 가 모달 DIV에서 *ngIf="details" 지시어를 제거합니다. 대신 *ngIf="details"을 내부 요소에 넣으십시오. 아마도 .modal-body 요소 또는 해당 요소의 내부에있는 컨테이너 div 일 수 있습니다.
    • 이 썸네일 버튼을 작품의 세부
  2. 이 함수의 첫 번째 라인으로 getArtworkDetail 다시 this.details = null; 추가로드 될 때까지 기다릴 필요없이 모달를 트리거 할 수 있습니다. 그러면 새 세부 정보가로드 될 때 모든 이전 세부 정보가 지워집니다.

원하는 시점에 요청이 완료 될 때까지 회 전자를 표시하고 싶을 것입니다. 이 경우 details 값이 null 인 동안 *ngIf="details" 지시문을 사용하여 회 전자를 제공 할 수 있습니다 (*ngIf="details; else spinner").


동료가 타이프 스크립트가 실행되기 전에 자바 스크립트로 컴파일됩니다 이후에이 오히려 타이프 라이터보다 자바 스크립트에 관해서와 실제로 언급 된 단일 스레드 성격. JavaScript는 실제로는 단일 스레드 이벤트 루프 (guaranteed이 아님)로 실행되지만 이러한 이벤트로 인해 트리거되는 특정 작업은 비동기 적으로 발생할 수 있습니다. 이러한 비동기 작업 중 하나가 XMLHttpRequest입니다. 이 문제는 비동기 적으로 발생하기 때문에 스크립트는 모달을 표시하려고 시도하기 전에 스크립트가 완료 될 때까지 기다릴 필요가 없습니다. 문제가있는 부분이 보입니다.

+1

감사합니다. 이것은 내 문제를 해결 :) –

1

As Mike Hill pointed out 솔루션은 내부 요소에 *ngIf를 추가하고 작동하지 않았다 내 this.details = null을 설정했지만, this.details = undefined IT는 modal-body*ngif와 같은 찾고 결국 이렇게 일 :

인덱스 .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">&times;</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...')); 
    }