2017-08-03 50 views
0

爲了測試目的,我在變化事件處理程序上連接了一個jQuery(我知道ng2具有可用(更改)屬性)。在my.component.ts文件,我可以成功地實現了以下事件處理程序的選擇在my.component.html直接放置在路由器出口下方:當輸入存在於* ngIf =「someData」時,如何通過ngAfterViewInit()添加事件處理程序來輸入?

ngAfterViewInit() 
{ 
    $('#ddlTest').on('change', function() { alert('jquery change wireup'); }); 
} 

然而,真正的選擇,我需要綁定到存在內一個div上的基礎組件成員變量顯示依賴性:

<div *ngIf="searchMetadata"> 
    <select id="ddlTest"> 
     <option>1</option> 
     <option>2</option> 
     <option>3</option> 
    </select> 
</div> 

成員變量被由組件設置調用服務並設置給變量的響應。我的問題是,看起來,ngIf容器阻止ngAfterViewInit事件連接邏輯找到嵌套的選擇輸入。我的猜測是ngAfterViewInit在ngIf條件實現之前在html中查找select。任何想法如何在維持ngIf的同時讓事件連接工作?

回答

0

您需要使用另一個鉤子。

ngAfterViewInit將在解析您的服務調用之前運行,因此jquery將永遠不會找到該#dd1Test選擇器。

當您更新searchMetadata運行此函數:

updateSearchMetadata(value: any): void { 
    this.searchMetadata = value; 
    setTimeout(() => this.watchJQuerySelectChanges() , 100); 
} 

watchJQuerySelectChanges(): void { 
    if (this.searchMetadata) { 
     $('#ddlTest').on('change', function() { alert('jquery change wireup'); }); 
    } 
} 

你也應該,如果你想使用#dd1TestonChange事件的內部角度使用NgZone(docs)。

要使用NgZone只是將其注入到構造函數:在onChange事件的回調

constructor(public ngZone: NgZone) 

然後使用jQuery只需添加這增加了:

$('#ddlTest').on('change',() => { 
    this.ngZone.run(() => { 
     this.searchMetadata = undefined; // Example to show that angular will see this. 
    }); 
}); 

更新最好的辦法

<div *ngIf="searchMetadata"> 
    <select #ddlTest id="ddlTest"> 
     <option>1</option> 
     <option>2</option> 
     <option>3</option> 
    </select> 
</div> 

Ť帽子將允許我們使用ViewChild

@ViewChild('ddlTest') 
set ddlTest(value: ElementRef) { 
    // keep the value if you want it for something. 
    $('#ddlTest').on('change',() => { 
     this.ngZone.run(() => { 
      // Do something 
      console.log('Hello there!'); 
     }); 
    }); 
} 
+0

感謝卡馬!我使用這樣的輸入裝飾器:@Input()searchMetadata,但change.searchMetadata返回一個錯誤:「屬性searchMetadata不存在'SimpleChanges'類型」。我需要如何改變我的實施?另外,僅僅使用「@Input()」裝飾組件成員變量searchMetadata來啓用ngOnChanges觸發器就足夠了嗎? – user8334943

+0

對不起,我的不好,更新 –

+0

沒有比setTimeout()更有條理的方法嗎? – user8334943

0

以下方法有效。它簡單直接。這是hacky,但它的作品。當addJQueryHook()命中時,上面的ddlTest已經被渲染。如果你知道更好的方法,那麼請注意!

<div *ngIf="SearchMetadata"> 
    <select id="ddlTest"> 
     <option>1</option> 
     <option>2</option> 
     <option>3</option> 
    </select> 
    <div *ngIf="addJQueryHook()"> 
    </div> 
</div> 
相關問題