2016-10-25 17 views
10

Tôi có cấu trúc cây đệ quy chứa các nút mà mỗi nút có thuộc tính 'htmlStringContent'. Khi tôi hiển thị cây sử dụng lồng nhau thành phần 'nút' và cố gắng trình bày các nội dung html tôi sử dụng:Hiển thị động các phần tử chứa các hàm HTML (nhấp) Angular 2

<div [innerHtml]="node.htmlStringContent"></div> 

Các màn HTML một cách chính xác nhưng đối với các yếu tố sau:

<a (click)="function()">click me</a> 

Các (nhấp chuột) chức năng không làm việc. Tôi biết điều này có previously been posted nhưng với số lượng lớn các bản cập nhật góc đã đưa ra gần đây tôi không thể tìm thấy bất kỳ giải pháp. This answer dẫn tôi tin rằng tôi nên sử dụng chỉ thị ngComponentOutlet nhưng tôi không chắc chắn như thế nào ..

Làm cách nào để có được góc cạnh để ràng buộc chức năng nhấp chuột này?

Chỉnh sửa: Tôi đã được yêu cầu sử dụng ComponentFactoryResolver nhưng không thể xem cách tôi có thể sử dụng điều này để hiển thị html chính xác. Bất cứ ai có thể cung cấp thêm trợ giúp?

Edit2: Tôi đang phân tích 'htmlStringContent' thông qua một đường ống vệ sinh trước khi hiển thị nó trên [innerHtml]

transform(v: string) : SafeHtml { 
    return this._sanitizer.bypassSecurityTrustHtml(v); 
} 

Edit3: Về cơ bản câu hỏi này được hỏi cho dù đó là vì tất cả có thể để hiển thị HTML từ một tài sản trên một đối tượng trong góc 2/ionic 2 trong khi vẫn giữ chức năng (nhấp) trên đó. Tôi cũng mở để giải đáp các câu trả lời.

+0

Sự kiện nhấp chuột theo cách này sẽ không hoạt động. Bạn có một thành phần tạo và sau đó bạn sẽ có thể tạo ra sự kiện nhấp chuột như đã được hiển thị trong một trong các liên kết của bạn. – micronyks

+0

@micronyks nhưng tôi vẫn sẽ phải sử dụng [innerHtml] để trình bày nội dung html? – alsco77

+1

Tôi hiểu rằng, nhưng giống như angular1, angular2 không có dịch vụ '$ compile' để bạn có thể thực hiện nó bằng cách sử dụng' componentFactoryResolver'. – micronyks

Trả lời

4

CFR DEMO: https://plnkr.co/edit/jKEaDz1JVFoAw0YfOXEU?p=preview

@Component({ 
    selector: 'my-app', 
    template: ` 

    <button (click)="addComponents()">Add HTML (dynamically using CRF)</button> 

    <h1>Angular2 AppComponent</h1> 
    <hr> 

    <div> 
    <h5>dynamic html goes here</h5> 
     <div class="container"> 
     <template #subContainer1></template> 
     </div> 
    </div> 


    `, 

}) 
export class App { 
    name:string; 
    @ViewChild('subContainer1', {read: ViewContainerRef}) subContainer1: ViewContainerRef; 

    constructor(
     private compFactoryResolver: ComponentFactoryResolver 
    ) { 
     this.name = 'Angular2' 
    } 

    addComponents() { 

     let compFactory: ComponentFactory; 

     compFactory = this.compFactoryResolver.resolveComponentFactory(Part1Component); 
     this.subContainer1.createComponent(compFactory); 

    } 
    } 
+0

I thấy rằng điều này tạo động các thành phần ..nhưng tôi đã có cấu trúc lồng nhau của các thành phần hiển thị bằng cách sử dụng đệ quy ngfor, giải pháp này sẽ trình bày chuỗi html chứa trong các thuộc tính thành phần và trình bày nó một cách chính xác, bao gồm chức năng nhấp chuột ?? – alsco77

3

Nếu tôi hiểu đúng, bạn cần phải sử dụng các mẫu năng động và biên dịch chúng trên runtime. Nếu vậy, thì bạn cần phải sử dụng trình biên dịch góc:

@Component({ 
    selector: 'my-app', 
    template: ` 
     <h1>Angular 2 Dynamic Component</h1> 
     <template #container></template> 
    ` 
}) 
export class AppComponent implements AfterContentInit, OnDestroy { 
    private dynamicComponentRefs: ComponentRef[] = []; 

    @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef; 

    constructor(private resolver: ComponentFactoryResolver, 
       private compiler: Compiler) {} 

    ngAfterContentInit() { 
    let html = ` 
     <div>Always Visible</div> 
     <div [hidden]="clause1">Hidden because of clause1 = true</div> 
     <div [hidden]="clause2">Visible because of clause2 = false</div> 
     <button type="button" (click)="buttonClicked()">Click me!</button> 
     <div *ngIf="clicked">You clicked the button!</div> 
    `; 

    this.compiler.compileModuleAndAllComponentsAsync(createDynamicComponent(html)) 
     .then((mwcf: ModuleWithComponentFactories) => { 
      let factory: ComponentFactory = mwcf.componentFactories.find(cf => 
      cf.componentType.name === 'DynamicComponent'); 
      this.dynamicComponentRefs 
       .push(this.container.createComponent(factory)); 
     }); 
    } 

    ngOnDestroy() { 
    /* Make sure you destroy all dynamically created components to avoid leaks */ 
    this.dynamicComponentRefs.forEach(dcr => { 
     dcr.destroy(); 
    }); 
    } 

} 

export function createDynamicComponent(html: string): Type<NgModule> { 
    @Component({ 
    template: html, 
    }) 
    class DynamicComponent { 
    private clause1: boolean = true; 
    private clause2: boolean = false; 
    private clicked = false; 

    buttonClicked() { 
     this.clicked = true; 
    } 
    } 

    @NgModule({ 
    imports: [CommonModule], 
    declarations: [DynamicComponent], 
    }) 
    class DynamicComponentModule {} 

    return DynamicComponentModule; 
} 

Về cơ bản bạn cần để tự động tạo ra một thành phần và các mô-đun mà tuyên bố nó (ví dụ thông qua một chức năng) và vượt qua nó các mẫu như một cuộc tranh cãi. Sau đó, bạn có thể gọi compileModuleAndAllComponentsAsync() trên mô-đun và nhận được nhà máy thành phần bạn cần. Sau đó, nó là vấn đề hiển thị nó trong DOM thông qua phương thức ViewContainerRef.createComponent().

Dưới đây là plunker làm việc: dynamic template component

Hãy ghi nhớ tuy nhiên đó - cho thời điểm này - phương pháp này chỉ có thể được sử dụng với JIT biên dịch. Trong biên dịch AOT trình biên dịch góc không có sẵn và cố gắng sử dụng nó sẽ ném một lỗi.

Các vấn đề liên quan