将模板添加为innerHTML时,Angular 2绑定/事件不起作用 [英] Angular 2 binding/events not working when adding template as innerHTML

查看:281
本文介绍了将模板添加为innerHTML时,Angular 2绑定/事件不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个可以配置的可重用表。可以将单元格配置为具有html模板。

I am trying to create a reusable table which can be configurable. The cells can be configured to have html template.

我正在配置列审核以使html模板具有带有click事件的锚标记(评论(行))。

I am configuring the column "Review" to have html template with anchor tag with click event (review(row)).

到目前为止,我试图将此模板作为innerHTML插入,但之后没有任何角度绑定工作。然后我尝试创建一个动态调用的组件(review.component.ts),但该组件仅为第一行调用一次。此外,我没有找到任何方法将当前行项目传递给点击事件审核(行)(在review.component.ts内)。

So far I tried to insert this template as innerHTML, but then none of the angular binding works. Then I tried to create a dynamically invoked component (review.component.ts) but this component invoked only once for first row. Moreover I didn't find any way to pass the current row item to click event review(row) (inside review.component.ts).

员工。 component.ts:

import { Component, OnInit, DynamicComponentLoader, ElementRef, Inject, Injector} from '@angular/core';
import { CORE_DIRECTIVES } from '@angular/common';
import {Router, RouteConfig, RouterLink, RouterOutlet, ROUTER_PROVIDERS, ROUTER_DIRECTIVES} from '@angular/router-deprecated';
import {DataTableComponent} from '../../data_table/data_table.component';
import {DataTable} from '../../data_table/dataTable';
import {Cell} from '../../data_table/cell';
import {ReviewComponent} from './review.component';

@Component({
    selector: 'employee',
    templateUrl: './app/employee/employee.html',
    directives: [DataTableComponent, ReviewComponent, RouterLink, RouterOutlet, ROUTER_DIRECTIVES],
    providers: [ROUTER_PROVIDERS]
})

export class EmployeeComponent implements OnInit {
    public tableConfig: DataTable;
    public constructor(private dcl: DynamicComponentLoader, private elementRef: ElementRef, private injector: Injector) {
        this.tableConfig = new DataTable();
        this.tableConfig.rows = [{ Sr: 1, Name: 'saurabh' }, { Sr: 2, Name: 'arun' }];
        var cellSr = new Cell();
        var cellName = new Cell();
        var cellReview = new Cell();
        cellSr.name = 'Sr';
        cellName.name = 'Name';

        //setting innerHtml directly doesn't work. Any way to make the bindings work in such case?
        //cellReview.innerHtml='<a class="btn btn-default" (click)="review(row)">Review</a>'

        cellReview.innerHtml = '<div class="child"></div>';
        this.tableConfig.cells = [cellSr, cellName, cellReview];
    }
    ngOnInit() {
        this.dcl.loadAsRoot(ReviewComponent, '.child', this.injector);
    }
}

review.component.ts:

import { Component} from '@angular/core';
import { CORE_DIRECTIVES } from '@angular/common';
import {Router, RouteConfig, RouterLink, RouterOutlet, ROUTER_PROVIDERS, ROUTER_DIRECTIVES} from '@angular/router-deprecated';

@Component({
    selector: 'btn-review',
    template: `<a class="btn btn-default" (click)="review(row)">Review</a>`,
    directives: [RouterLink, RouterOutlet, ROUTER_DIRECTIVES],
    providers: [ROUTER_PROVIDERS]
})

export class ReviewComponent {
    constructor() {}
    public review(event){
        console.log(event);
        console.log(2);
    }
 } 

datatable.ts:

import {Cell} from './cell';
export class DataTable {
    rows: Array<any>;
    cells: Cell[];
}

data_table.component.ts:

import { Component, Input } from '@angular/core';
import { CORE_DIRECTIVES } from '@angular/common';
import {Router, RouteConfig, RouterLink, RouterOutlet, ROUTER_PROVIDERS, ROUTER_DIRECTIVES} from '@angular/router-deprecated';
import {TAB_DIRECTIVES} from 'ng2-bootstrap';
import {DataTable} from './dataTable';
import {Cell} from './cell';
@Component({
    selector: 'data-table',
    templateUrl: './data_table/data_table.html',
    directives: [RouterLink, RouterOutlet, ROUTER_DIRECTIVES],
    providers: [ROUTER_PROVIDERS]
})
export class DataTableComponent {
    @Input() dataTable: DataTable;   
    bindCell(cell: Cell, row: any) {
        var text = '';
        if (cell.innerHtml && cell.innerHtml.length > 0) {
            return cell.innerHtml;
        }
    }   
}

data_table.html :

<table>
    <tbody>
        <tr *ngFor="let row of dataTable.rows">
            <td *ngFor="let cell of dataTable.cells" [innerHTML]="bindCell(cell, row)">
            </td>
        </tr>
    </tbody>
</table>


推荐答案

Angular不处理使用<$ c添加的HTML $ c> innerHtml (也是 ElementRef.nativeElement.append(...)或类似的)以任何方式。

Angular doesn't process HTML added using innerHtml (also ElementRef.nativeElement.append(...) or similar) in any way.

如评论中所提到的,另一种方法是将HTML包装在一个组件中并动态添加该组件。不推荐使用 DynamicComponentLoader (如评论中的链接答案所示)。它被 ViewContainerRef.createComponent()取代。 带有用户点击选定组件的Angular 2动态标签显示了如何使用它的示例。

As mentioned in the comment an alternative is to wrap the HTML in a component and add this component dynamically. DynamicComponentLoader (as shown in the linked answer from the comment to your question) is deprecated. It was replaced by ViewContainerRef.createComponent(). Angular 2 dynamic tabs with user-click chosen components shows an example how to use it.

这篇关于将模板添加为innerHTML时,Angular 2绑定/事件不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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