2017-08-28 10 views
1

私はレコードのテーブルを含む作業しているコンポーネントがあります。この表の各行には、コンテンツをモーダルで編集できる編集ボタンがあります。角度成分の放出が予想よりも多いですか?

私のモーダルの内容をレンダリングする私の機能にはconsole.logが投げられました。私は奇妙な動作に気付いています。モーダルを閉じるたびに、私のconsole.logはクリックごとに時間がかかるようです。たとえば、ロード時には、Editをクリックします。結果はconsole.log('test');です。モーダルを閉じてもう一度編集をクリックすると(コンソールがクリアされている)、私はconsole.log('test');という2つのインスタンスを取得します。

私は、何かが正しく動作していないこと、そしてそれよりも多く発射されているということに少し懐疑的です。

結果表コンポーネント:この表のデータを使用した

<!-- Loading Indicator --> 
<div *ngIf="!exceptions" class="loader" align="center"> 
    <img src="images/loading-bars.svg" alt="" /> 
</div> 
<!-- Loading Indicator --> 

<!-- Active Exceptions --> 
<span *ngIf="exceptions"> 
    <table class="table table-condensed" *ngIf="exceptions.activeExceptions"> 
     <thead> 
      <tr> 
       <th class="small">Employee</th> 
       <th class="small">Start Date</th> 
       <th class="small">End Date</th> 
       <th class="small">Exception Outcome</th> 
       <th class="small">Action</th> 
      </tr> 
     </thead> 
     <tbody> 
      <tr *ngFor="let e of exceptions.activeExceptions.data"> 
       <td [innerHtml]="e.EmpNTID | ntidLink"></td> 
       <td class="small">{{ e.ExceptionStartDate }}</td> 
       <td class="small">{{ e.ExceptionEndDate === '2050-12-31' ? 'Indefinitely' : e.ExceptionEndDate }}</td> 
       <td class="small"><strong>{{ e.Value }}</strong></td> 
       <td class="small"> 
        <button type="button" class="btn btn-default btn-xs" (click)="doEditException(e)"> 
        <i class="fa fa-pencil"></i>&nbsp;&nbsp;Edit Exception 
        </button> 
       </td> 
      </tr> 
     </tbody> 
    </table> 
    <!-- Active Exceptions --> 

    <!-- No Active Exceptions --> 
    <span *ngIf="!exceptions.activeExceptions"> 
     <div class="alert alert-warning"><i class="fa fa-comment padRight"></i>No Active Exceptions</div> 
    </span> 
    <!-- No Active Exceptions --> 

</span> 

コンポーネント関連:編集ボタンクリックがdoEditExceptionメソッドにバインドし、モーダルの内容をロードしている

export class ActiveExceptionsComponent implements OnInit { 

    @Input() exceptions: any; 
    @Output() doEdit:EventEmitter<any> = new EventEmitter(); 

    constructor(
     public bsModalRef: BsModalRef, 
     private modalService: BsModalService, 
     private _mapsService: MapsService, 
    ) { 
    } 

    ngOnInit() { 
     // 
    } 

    /** 
    * On "Edit" of an exception, trigger our modal. 
    * The modal will include its own component. 
    * 
    * @param {any} $event 
    * @memberof ExceptionsComponent 
    */ 
    doEditException($event) { 

     // Call our modal, pass the EditExceptionModalComponent 
     this.bsModalRef = this.modalService.show(EditExceptionModalComponent); 

     // Call next on our behavior subject to update the modal subscriber data 
     this._mapsService.updateExceptionModalData({ 
      event: $event, 
      exceptionTypes: this.exceptions.exceptionTypes 
     }); 

    } 

別のコンポーネントで

モーダルコンポーネント:

export class EditExceptionModalComponent implements OnInit { 

    exceptionForm: FormGroup; 
    modalData: any; 

    // Configuration for the date pickers 
    datesConfig = { 
     'format': 'YYYY-MM-DD', 
     'placeholder': 'Choose a date...' 
    } 

    constructor(
     private fb: FormBuilder, 
     public bsModalRef: BsModalRef, 
     private _mapsService: MapsService, 
    ) { } 

    ngOnInit() { 

     // Subscribe to the modal data received from the active/future exceptions component 
     this._mapsService.uiExceptionModalData.subscribe(
      results => { 
       if (results) { 
        this.modalData = results; 
        this.renderForm(); 
       } 
      } 
     ); 

    } 

    /** 
    * Render the form for the contents of the modal 
    * 
    * @memberof EditExceptionModalComponent 
    */ 
    renderForm() { 

     console.log('here'); <---- Each time the parent component edit button is clicked, this method gets executed 1 more time than previous. 

     // Determine if this exception expires or not 
     let isIndefinite = (this.modalData.event.ExceptionEndDate == '2050-12-31' ? true : false); 

     // Render our modal form 
     this.exceptionForm = this.fb.group({ 
      outcome: [[{ text: this.modalData.event.Value, id: this.modalData.event.MappedValue }]], 
      startDate: this.modalData.event.ExceptionStartDate, 
      endDate: [{ value: (!isIndefinite ? this.modalData.event.ExceptionEndDate : ''), disabled: (isIndefinite ? true : false) }], 
      indefinite: (isIndefinite ? '1' : ''), 
      exceptionUser: this.modalData.event.QID, 
      exceptionID: this.modalData.event.ExceptionID, 
      targetID: this.modalData.event.TargetID, 
     }); 

    } 

} 

そして最後に、モーダルコンテンツのHTML:

<div *ngIf="modalData"> 
    <div class="modal-header text-center"> 
     <h4 class="modal-title">Edit Exception</h4> 
     <small>Editing rule exception for <strong>{{ modalData.event.EmpName }}</strong></small> 
    </div> 
    <div class="modal-body"> 
     <form [formGroup]="exceptionForm" #f="ngForm"> 
      <div class="form-group"> 
       <label for="exceptionOutcome">Exception Outcome</label> 
       <ng-select formControlName="outcome" [allowClear]="false" [items]="getExceptionTypes()" placeholder="Select an Exception Outcome"> 
       </ng-select> 
      </div> 
      <div class="form-group noBottomMargin"> 
       <label for="exceptionStartDate">Start Date</label> 
       <input type="text" class="form-control input-sm" formControlName="startDate" [dpDayPicker]="datesConfig" theme="dp-material" 
        placeholder="Choose a Start Date"> 
      </div> 
      <div class="form-group noBottomMargin"> 
       <label for="exceptionEndDate">End Date</label> 
       <div class="input-group"> 
        <input type="text" class="form-control input-sm" formControlName="endDate" [dpDayPicker]="datesConfig" theme="dp-material" 
         placeholder="Choose a End Date"> 
        <div class="input-group-addon"><input type="checkbox" (click)="toggleIndefiniteCheckbox(true)" value="1" formControlName="indefinite" [value]="value" [attr.checked]="value" id="indefinitely"> Indefinitely</div> 
       </div> 
      </div> 
      <input type="hidden" formControlName="exceptionID"> 
      <input type="hidden" formControlName="targetID"> 
     </form> 
    </div> 
    <div class="modal-footer"> 
     <button type="button" class="btn btn-default" (click)="bsModalRef.hide()">Close</button> 
     <button type="button" class="btn btn-primary" (click)="saveChanges(exceptionForm.getRawValue())">Save changes</button> 
    </div> 
</div> 

ここでの私の関心は、renderForm方法がのロードごとに複数回呼び出されていることですモーダル、私は親のdoEditExceptionメソッドを起動するたびに1ずつ増加します。

何かを正しく終了したりリセットしたりしないとこの現象が起こりますか?私の期待は、親コンポーネントの「編集」ボタンをクリックすると、子供のrenderFormメソッドが1回だけ呼び出されることがわかります。この方法の中で私のconsole.logが毎回増加しているようには見えません。

+0

あなたの 'ngOnInit'コール内で作成されたサブスクリプションを解除していない、' 'サブスクライブする前に(1)を取る使用するようにしてください。 – cyrix

+0

@cyrix - 私は "take"について聞いたことがありません。どのように使用されているかの例はありますか? – SBB

+0

この 'this._mapsService.uiExceptionModalData.take(1).subscribe(...)'のように、答えを見て、それも動作します。 – cyrix

答えて

1

問題は、結果のサブスクリプションをサブスクライブしないことです。あなたはあなたのモーダルが破壊されたときに退会する必要があります。あなたのモーダルコンポーネントで

import { Subscription } from 'rxjs/Subscription'; 
// .... 

private sub: Subscription; 
ngOnInit() { 
    // Subscribe to the modal data received from the active/future exceptions component 
    this.sub = this._mapsService.uiExceptionModalData.subscribe(
     results => { 
      if (results) { 
       this.modalData = results; 
       this.renderForm(); 
      } 
     }); 
} 

ngOnDestroy() { 
    // Unsubscribe here. 
    this.sub.unsubscribe(); 
} 
+0

これを追加しましたが、「編集」をクリックするたびに増分されなくなりました。私は 'renderForm'メソッドで2つの' console.log'呼び出しを取得しています。これについては? – SBB

+0

これは何らかの他のエラーである可能性がありますが、これは複数のサブスクリプションの問題を解決します。あなたの 'renderForm()'メソッドは2回呼び出されますか? – Faisal

+0

親コンポーネントの「編集」ボタンをクリックすると、私の 'renderForm()'メソッドから2つの 'console.log( 'ここ')'出力が得られます。 – SBB

関連する問題