Angular 2用div via指令包围输入标签

时间:2017-04-07 15:52:35

标签: angular angular2-directives

我正在尝试创建一个带有输入元素的指令并用div包围它,所以例如,我的html会是这样的:

<input type="text" class="form-control" inputWrapper />

和期望的结果:

<div class="input-wrapper">
    <input type="text" class="from-control" />
</div>

指令:

@Directive({
    selector: '[inputWrapper]'
})
export class InputWrapperDirective {
    constructor(private viewContainerRef: ViewContainerRef, private elementRef: ElementRef) {
        // what goes here?
    }
}

3 个答案:

答案 0 :(得分:14)

这是你如何用指令做的。代码使用Renderer2,我认为是Angular 4.可能使用Renderer(现在标记为已弃用)可以实现同样的目的

我在ngAfterViewInit方法中完成了所有工作。您可能会使用构造函数。

import { Directive, Renderer2, ElementRef, AfterViewInit } from '@angular/core'

@Directive({
    selector: '[inputWrapper]'
})
export class InputWrapperDirective implements AfterViewInit {
    constructor(private _renderer:Renderer2, private _el: ElementRef) {

    }

    ngAfterViewInit() {
        // Get parent of the original input element
        var parent = this._el.nativeElement.parentNode;

        // Create a div
        var divElement = this._renderer.createElement("div");

        // Add class "input-wrapper"
        this._renderer.addClass(divElement, "input-wrapper");

        // Add the div, just before the input
        this._renderer.insertBefore(parent, divElement, this._el.nativeElement);

        // Remove the input
        this._renderer.removeChild(parent, this._el.nativeElement);

        // Remove the directive attribute (not really necessary, but just to be clean)
        this._renderer.removeAttribute(this._el.nativeElement, "inputWrapper"); 

        // Re-add it inside the div
        this._renderer.appendChild(divElement, this._el.nativeElement);

    }

}

答案 1 :(得分:2)

我会使用一个组件......

以下是我要做的事情:

@Component({
    selector: 'input-wrapper',
    template: '<div><ng-content></ng-content></div>'
})
export class InputWrapperComponent {}

在模板中,<ng-content>标记表示无论您的<input-wrapper>标记被包裹在哪里,都会进入此处。

请注意,此组件模板为<div><ng-content></ng-content></div>。您可以将“div”更改为您想要的任何内容......

无论你想在哪里使用它,你都不会只是注释标签,你需要做这样的事情:

<input-wrapper>
    <!-- Anything you want wrapped goes here -->
</input-wrapper>

这是可以重复使用的...更改模板,您将更改所有包装。

答案 2 :(得分:1)

这是另一个版本,这个版本适用于Renderer,而不是Renderer2。请注意,我在构造函数中执行此操作,将其推迟到AfterViewInit不起作用。

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

@Directive({
    selector: '[inputWrapper]'
})
export class InputWrapperDirective {
    constructor(private _renderer:Renderer, private _el: ElementRef) {
        // Remove the inputWrapper attribute (not really necessary, but just to be clean)
        this._renderer.setElementAttribute(this._el.nativeElement, "inputWrapper", null);

        // Get parent of the original input element
        var parent = this._el.nativeElement.parentNode;

        // Create a div and add it to the parent
        // Note: it seems that Renderer creates the element in the right place,
        // no need to specify where.
        var divElement = this._renderer.createElement(parent, "div");

        // Add class "input-wrapper"
        this._renderer.setElementClass(divElement, "input-wrapper", true);

        // Move the input as a child of the div
        divElement.appendChild(this._el.nativeElement);
    }
}