数据绑定ng2组件的模板仅设置OnInit [英] Data-binding ng2 component's template only set OnInit

查看:98
本文介绍了数据绑定ng2组件的模板仅设置OnInit的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个角度2(RC5)组件,它进行HTTP调用并将结果设置为组件的模板。我想在HTTP调用返回的HTML中注入一个值。例如,返回的HTML中的一行是:

I have an angular 2 (RC5) component which makes an HTTP call and sets the result as the template of the component. I want to inject a value into the HTML that is returned by the HTTP call. so for example, one of the lines in the returned HTML is:

<a class="d2h-file-name" href="{{chapterURL}}">app/views/login/login.xml</a>

然而,在没有注入chapterURL的情况下,完全按原样呈现。据推测,这是因为在初始化过程中没有设置模板?如果是这样,我应该如何将这些动态值注入模板?

However, that is rendered exactly as is, without having the chapterURL injected. Presumably, this is because the template isn't set during the initialization process? If so, How should I inject these dynamic values into the templates?

这是组件。

@Component({
    selector: 'codestep',
    template: `<div class="codestep" [innerHTML]="content"></div>`
})
export class codeStepComponent {
    @Input() step: string;
    private content: string = '';
    private chapterURL;

    constructor(private route: ActivatedRoute, private http: Http) { }

    ngOnInit() {
        this.chapterURL = './diff/' + this.step + '.html';
        this.getChapter()
            .subscribe(
            chapterContent => this.content = chapterContent,
            error => this.errorMessage = <any>error);
    }

    getChapter(): Observable<any> {
        return this.http.get(this.chapterURL)
            .map(this.extractData)
            .catch(this.handleError);
    }
    private extractData(res: Res) {
        let body = res._body;
        return body;
    }
    //Error handling function here...
}



< h1>编辑:

我已将http调用返回的源html文件更改为:

I have changed the source html file which is returned by the http call, to:

<a class="d2h-file-name" href={{chapterURL}}>app/views/login/login.xml</a>

然后将组件的模板更改为:

and then changed the component's template to:

template: `<div class="codestep" [innerHTML]="content|rawHtml"></div>`

其中 rawHtml 是一个使用 bypassSecurityTrustHtml清理内容的管道( )函数在 DomSanitizationService 但是,我仍然得到相同的结果,渲染的结果是:

where rawHtml is a pipe that sanitises the content with the bypassSecurityTrustHtml() function on the DomSanitizationService however, I still get the same result, the rendered result is:

<a class="d2h-file-name" href="gitURL">app/views/login/login.xml</a>

如果我 ng.probe($ 0)使用浏览器中选择的组件,然后返回的结果对象具有属性,但列出的唯一属性是 innerHTML ,没有其他...

if I do ng.probe($0) with the component selected in the browser, then the returned resultant object has properties, but the only property listed is innerHTML, nothing else...

推荐答案

2方法

如果数据只需要在初始化期间更新一次,这很简单。

This is simple and easy, if the data only need to be updated once during initialization.

ngOnInit() {
    this.chapterURL = './diff/' + this.step + '.html';
    this.getChapter()
        .subscribe(
        chapterContent:string => {

            // Pre-process the content
            processedContent = chapterContent.replace('{{chapterURL}}',this.chapterURL);

            this.content = processedContent;
        },
        error => this.errorMessage = <any>error);
}



方法2 - 动态组件



Angular 2不支持组件模板运行时更新。

Method 2 - dynamic component

Angular 2 does not support component template run time update.

innerHTML 将不符合您的要求Angular2不会解析它的内容。因此,innerHTML中的数据绑定将不起作用。

innerHTML will not meet your requirement as Angular2 will not parse the content of it. So data binding within innerHTML will not work.

要归档运行时模板更新,或者更确切地说,运行时模板生成使用动态组件。

To archive run time template update, or more precisely, run time template generation is using dynamic component.

RadimKöhler的详细解答如下:
https:// stackoverflow .com / a / 38888009/1810391

There is a detail answer with example here by Radim Köhler: https://stackoverflow.com/a/38888009/1810391

http://plnkr.co/edit/iXckLz?p=preview

以下是我放在一起的非常简约的例子:

Following is a very minimalistic example I put together:

cf.com.ts

import { Component, ComponentRef, ViewChild, ViewContainerRef } from '@angular/core';

import { RuntimeCompiler } from '@angular/compiler';

import { CfModule } from './cf.module';

@Component({
    selector: 'cf-com',
    template: `
        <h1>{{title}}</h1>
        <button (click)="template1()">Template 1</button>
        <button (click)="template2()">Template 2</button>
        <button (click)="moreChild()">More Child</button>
        <template [ngIf]="childRef" #child></template>`
})
export class CfCom {
    title = 'Component Factory Test';

    // reference for html element with #child tag
    @ViewChild('child', { read: ViewContainerRef }) protected childComTarget: ViewContainerRef;
    // Child component reference
    protected childRef: ComponentRef<any>;

    constructor(private compiler: RuntimeCompiler) { }

    // Child Input. Use object, not basic type
    childInput = { counter: 0 };

    // Click to get more children
    moreChild() {
        this.childInput.counter++;
    }

    // Click to use template 1
    template1() {
        let t = 'Child:{{j.counter}}';
        this.createChild(t);
    }

    // Click to use template 1
    template2() {
        let t = 'Children:{{j.counter}}';
        this.createChild(t);
    }

    createChild(t: string) {
        // Destroy child if exist
        if (this.childRef) {
            this.childRef.destroy();
            this.childRef = null;
        }

        // cf-child class
        @Component({
            selector: 'cf-child',
            template: t // template from parameter t
        })
        class CfChildCom {
            j; // will be bind with parent childInput, see below
        }

        this.compiler.compileComponentAsync<any>(CfChildCom, CfModule)
            .then(factory => {
                this.childRef = this.childComTarget.createComponent(factory, 0);

                // This is how parent variable bind with child variable
                this.childRef.instance.j = this.childInput;
            });
    }
}

cf.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { COMPILER_PROVIDERS } from '@angular/compiler';

import { CfCom } from './cf.com';

@NgModule({
    imports: [BrowserModule],
    exports: [CfCom],
    providers: [COMPILER_PROVIDERS],
    declarations: [CfCom]
})
export class CfModule { }

这篇关于数据绑定ng2组件的模板仅设置OnInit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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