简体   繁体   English

当* ngIf =“ someData”中存在输入时,如何通过ngAfterViewInit()向输入添加事件处理程序?

[英]how to add event handler to input via ngAfterViewInit() when input exists in *ngIf=“someData”?

I'm hooking up a jQuery on change event handler for test purposes (I know ng2 has an available (change) attribute). 我为了测试目的将jQuery连接在更改事件处理程序上(我知道ng2具有可用的(更改)属性)。 In my.component.ts file I can implement the following event handler successfully for a select placed directly below the router-outlet in my.component.html: 在my.component.ts文件中,我可以为my.component.html中路由器出口正下方的选择成功实现以下事件处理程序:

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

However, the real select I need to bind to exists within a div displayed dependent on an underlying component member variable: 但是,我需要绑定的实际选择项存在于根据基础组件成员变量显示的div中:

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

The member variable gets set by the component calling a service and setting the response to the variable. 成员变量由组件调用服务并设置对该变量的响应来设置。 My problem is that it appears that the *ngIf container prevents the ngAfterViewInit event wireup logic from finding the nested select input. 我的问题是* ngIf容器似乎阻止ngAfterViewInit事件关联逻辑查找嵌套的选择输入。 My guess is that ngAfterViewInit looks for the select in the html before the ngIf condition has been actualized. 我的猜测是ngAfterViewInit在ngIf条件实现之前在html中查找选择。 Any idea how I can get the event wireup working while maintaining the ngIf? 知道如何在维护ngIf的情况下使事件联动工作吗?

You need to use another hook. 您需要使用另一个挂钩。

ngAfterViewInit will run before you resolve your service call, so jquery will never find that #dd1Test selector. ngAfterViewInit将在您解决服务调用之前运行,因此jquery将永远找不到该#dd1Test选择器。

When you update your searchMetadata run this function instead: 当您更新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'); });
    }
}

Also you should use NgZone ( docs ) if you want to use angular inside of the #dd1Test onChange event. 如果要在#dd1Test onChange事件中使用angular,也应使用NgZone( docs )。

To use NgZone just inject it to the constructor: 要使用NgZone,只需将其注入构造函数中即可:

constructor(public ngZone: NgZone)

Then in the callback of the onChange event added using jquery just add this: 然后在使用jquery添加的onChange事件的回调中添加以下内容:

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

Update The best way 更新最佳方法

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

That will allow us to use the ViewChild . 这将使我们能够使用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!');
        });
    });
}

The following approach works. 以下方法有效。 It's simple and straight forward. 简单而直接。 It's hacky but it works. 这很hacky,但是可以用。 When addJQueryHook() gets hit, ddlTest above will already be rendered. 当addJQueryHook()被命中时,上面的ddlTest将已经被渲染。 If you know a better way then please lmk! 如果您知道更好的方法,请lmk!

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM