viewChild可以如何在角度2中获取添加js的元素? [英] How viewChild can get elements that added with js in angular2?

查看:294
本文介绍了viewChild可以如何在角度2中获取添加js的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果HTML元素已被添加到DOM中(例如点击按钮后),我们如何访问这个元素?



更新1:更多说明



I已使用jquery datatable(



使用Chrome Developer工具,我看到:



第一个锚标签工作,但使用href,而不是routerLink。



第二个锚标签因为角度指令没有符合href。



我试图使用DynamicComponentLoader编译它,并更改了如下代码:



但是我无法使用viewChild访问#target元素(我想用另一个组件通过loadNextToLocation更改它)。我想这不是最佳的方式来获得好的结果。



我想在jquery datatable里面使用routerLink与命令按钮。



请问您能帮助我正确的方向来解决吗?



提前谢谢。



解决方案:



如果要使用javascript或某些回调函数将DOM添加到DOM,首先要从模板中确定一个可以作为这些元素)


  1. 将模板变量添加到此父元素(例如,#target)





     < th>电子邮件< / th> 
    < th>日期< / th>
    < th>电话< / th>
    < th>命令< / th>


    < / tr>
    < / thead>
    < tbody#target>< / tbody>
    < tfoot>
    < tr>

    < th> < / th>
    < th> < / th>
    < th> < / th>
    < th> < / th>

    < / tr>
    < / tfoot>
    < / table>


  2. 然后在您的html代码中添加一个简单的类和一个简单的属性(此代码生成另外您可以使用typescript或javascript编写一些代码来生成html)。

      columnDefs:[
    {
    render:function(data,type,row){
    return`
    `< a date-id =`+ row.UserId +`class =editbtn btn btn-outline btn-circle btn-sm red>编辑< / a>
    `;
    },
    目标:5
    },
    ],


  3. 现在导入并将这些源注入到您的组件中:

      import {ViewChild,Renderer} from'@角/核心

    和:

     code> constructor(private renderer:Renderer,private router:Router)


  4. 定义您的组件类中的viewChild变量:

      @ViewChild('target')target; 


  5. 编写一个这样的功能:

      public AfterEverything(){
    var el:HTMLElement = this.target.nativeElement; //创建元素对象
    console.log(el);
    var commands:NodeListOf< Element> = el.getElementsByClassName('editbtn'); //查找元素对象以获得具有特定类的所有元素
    console.log(commands);
    for(var i = 0; i< commands.length; i ++){
    //循环添加事件或样式
    console.log(commands [i]);
    //示例事件(点击路由)
    this.renderer.listen(命令[i],'点击',(事件:事件)=> {
    var thisid = event。 srcElement.getAttribute(date-id); //从元素
    获取值$ console.log(thisid);
    this.router.parent.navigate(['EditUser',{id:thisid} ]); //使用值使routeLink
    console.log(event.srcElement.innerHTML);
    });
    this.renderer.setElementStyle(commands [i],'backgroundColor','yellow'); //为更改颜色(只是样本)
    }
    / pre>

    }


  6. 你必须找到最好的地方来调用这个功能,例如ajax数据回调是一个选择,并在其中调用AfterEverything()。您可以在ngAfterViewInit()中调用此函数。


请注意,有时需要几秒钟的延迟才能确保创建所有新元素。 / strong>

解决方案

可以通过以下方式使用viewChild:


  1. 在你的返回元素中添加一个类:



    columnDefs:[{
    render:function(data,type,row){
    return'< span class =target-classdata-id ='+ data.id +'>更改密码< / span> ;
    },
    目标:5
    }
    ]


  2. 路由器进入你的sample.component.ts并在类构造函数中初始化它



    import {Router} from'@ angular / router';
    export class SampleComponent {
    constructor(private router:Router){}
    }


  3. 使用router.navigate函数添加一个点击事件到您的表上的'.target-class'

    $('#table-id ').on('click','.target-class',function(){
    let userId = $(this).data('id');
    router.navigate(['/ users /',userId])
    });



If a HTML element has been added to the DOM(for example after click on button), How can we access this element? viewChild can't see that.

Update 1: More description

I've used jquery datatable (jquery.dataTables definitelyTyped version). Base on this link, I can add new column and define html inside that. I wrote this code :

           columnDefs: [
                    {
                        render: function (data, type, row) {
                            return `
                                  <a href="admin/edituser/` + row.UserId+ `" class="btn btn-outline btn-circle btn-sm green"><i class="fa fa-edit" > </i> Edit </a>`+
                                 `<a [routerLink]="['Delete']" class="btn btn-outline btn-circle btn-sm red"><i class="fa fa-trash-o" > </i> Delete </a>
                                            `;
                        },
                        targets: 5
                    },
                ],

With Chrome Developer tools I see this :

First anchor tag works but with href, not routerLink.

Second anchor tag doesn't work because angular directives didn't complie to href.

I tried to use DynamicComponentLoader to compile it, and changed code like this:

But I can't access #target element with viewChild.(I want to change it with another component by loadNextToLocation). I think this isn't optimize way to get good result.

I want to use routerLink with commands buttons inside jquery datatable.

Could you please help me in the right direction to solve this?

Thank you in advance.

solution :

If you want to add HTML to DOM with javascript or some callback function first determine a tag from template that can be a parent for those element(s) in future.

  1. Add template variable to this parent element.(#target for example)

                    <th> Email</th>
                    <th> Date </th>
                    <th> Phone </th>
                    <th> Commands</th>
    
    
                </tr>
            </thead>
            <tbody #target></tbody>
            <tfoot>
                <tr>
    
                    <th>  </th>
                    <th>  </th>
                    <th>  </th>
                    <th>  </th>
    
                </tr>
            </tfoot>
        </table>
    

  2. Then add a simple class and a simple attribute to your html code(This code is generated after page compiled with angular,Also you can write some code with typescript or javascript to generate html).

       columnDefs: [
                    {
                        render: function (data, type, row) {
                            return `
                                 `<a date-id="` + row.UserId + `" class="editbtn btn btn-outline btn-circle btn-sm red"> Edit</a>
                                 `;
                        },
                        targets: 5
                    },
                ],
    

  3. Now import and inject these sources to your component:

        import {ViewChild, Renderer} from '@angular/core';
    

    and :

        constructor(private renderer: Renderer, private router: Router)
    

  4. Define a viewChild variable in your component class:

        @ViewChild('target') target;
    

  5. Write a function like this :

    public AfterEverything() {
           var el: HTMLElement = this.target.nativeElement;//Make an Element Object
           console.log(el);
           var commands: NodeListOf<Element> = el.getElementsByClassName('editbtn');//Find Element Object to get all elements with a specefic class
           console.log(commands);
           for (var i = 0; i < commands.length; i++) {
               //Loop for add event or style
               console.log(commands[i]);
               //Sample event(Click for routing)
               this.renderer.listen(commands[i], 'click', (event: Event) => {
                   var thisid = event.srcElement.getAttribute("date-id");//Get value from element
                   console.log(thisid);
                   this.router.parent.navigate(['EditUser', { id: thisid }]);//Use value to make routeLink
                   console.log(event.srcElement.innerHTML);
               });
               this.renderer.setElementStyle(commands[i], 'backgroundColor', 'yellow');//for change color(just sample)
           }
    

    }

  6. You must find best place to call this function,for example, ajax data callback is one choice and call AfterEverything() inside that. You can call this function inside ngAfterViewInit().

Note that sometimes a delay of several seconds is necessary to ensure that all new elements are created.

解决方案

You can do this without using viewChild via the following:

  1. add a class to your return element:

    columnDefs: [{ render: function (data, type, row) { return '<span class="target-class" data-id="' + data.id + '">Change Password</span>'; }, targets: 5 } ]

  2. import angular router into your sample.component.ts and initialize it in the class constructor

    import { Router } from '@angular/router'; export class SampleComponent { constructor(private router: Router) { } }

  3. add a click event to the '.target-class' on your table with a router.navigate function

    $('#table-id').on('click', '.target-class', function(){ let userId = $(this).data('id'); router.navigate(['/users/', userId]) });

这篇关于viewChild可以如何在角度2中获取添加js的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆