使用Renderer和ElementRef修改组件

时间:2015-12-27 23:32:19

标签: javascript css typescript ecmascript-6 angular

1 ISSUE

我正在尝试实施以下内容:

我有一个容器组件ContainerComponent和子组件ChildComponent。我想通过控制ContainerComponent来修改子组件的呈现和整体行为。

2使用的技术

Angular2HTMLCSSJavascriptTypescriptES6

3 CODE

ContainerComponent.ts

export class ContainerComponent {

    children: Array<Child>;

    constructor(
        private _el: ElementRef,
        private _dcl: DynamicComponentLoader,
        private _childService: ChildService) {

    }

    ngOnInit() {

        let index = 0; // index of child component in container
        this._childService.getChildren().then( // get the children models
            (children) => {

                this.children = children; 
                this.children.forEach((child, index) => {
                    this._dcl.loadIntoLocation(ChildComponent, this._el, 'dynamicChild')
                    .then(function(el){
                        el.instance.child = child; // assign child model to child component
                        el.instance.index = index;
                    });
                });

            }
        );

    }

}

ChildComponent.ts

export class ChildComponent {

    child: Child;
    index: number;

    constructor(private _renderer: Renderer, private _el: ElementRef) {
    }

    ngOnInit() {

        let delay = (this.index + 1) * 0.5; // calculate animation delay
        this._renderer.setElementStyle(this._el, '-webkit-animation-delay', delay + 's !important');
        this._renderer.setElementStyle(this._el, 'animation-delay', delay + 's !important');

    }

}

4代码说明

在上面的代码中,ContainerComponent动态插入ChildComponent(已授予,这可以在没有DynamicContentLoader的情况下完成)。

ChildComponents应该动态添加css属性,在这种情况下,一旦显示动画延迟。因此,基于孩子的索引,动画延迟增加。

但是,渲染器的修改不会生效,css属性在运行时不存在。

3 个答案:

答案 0 :(得分:1)

我试图重现你的问题。实际上,我在添加-webkit-animation-delayanimation-delay等样式时遇到问题。

如果我尝试使用color之类的其他样式,它可以正常运行并在运行时考虑该样式。

ngOnInit() {
    this._renderer.setElementStyle(this._el, 'color', 'yellow');
}

所以它似乎与动画风格有关......我看到这些链接可能让你感兴趣:

否则似乎在Angular2中对动画有一些支持,但它没有真正记录......请参阅此文件:https://github.com/angular/angular/blob/master/modules/angular2/src/animate/animation.ts

希望它可以帮到你, 亨利

答案 1 :(得分:0)

这似乎是angular2本身的一个错误。将!important添加到样式将导致样式的非法值,并且不会将其应用于该元素。普通js中的正确方法是使用另一个参数,暗示风格是否重要。

所以正确的答案是使用:

this._renderer.setElementStyle(this._el, 'animation-delay', delay + 's'); //sans !important

如果你想添加!important,你必须使用:

this._el.nativeElement.style.setProperty('animation-delay', delay + 's', 'important');

如果需要,可以添加(或删除)-webkit-前缀,因此无需添加

答案 2 :(得分:0)

从这里开始:

https://angular.io/docs/ts/latest/api/core/ElementRef-class.html

您应该只使用ElementRef作为绝对的最后资源。 Angular 2的整个想法是你根本不必弄乱dom。使用模板可以很容易地完成您想要做的事情:

import {NgStyle} from 'angular2/common';
import {Component} from "angular2/core";

@Component({
    selector: 'app',
    template: `
        <div *ngFor="#child of children; #i = index">
            <div [ngStyle]="{ 'z-index': i * multiplier,
                                '-webkit-animation-delay': i * multiplier + 's',
                                 'animation-delay': i * multiplier + 's' }"> {{i}} - {{child}} </div>
        </div>
    `,
    directives: [NgStyle]
})
export class AppComponent{
    public children:string[] = [ "Larry", "Moe", "Curly" ];
    public multiplier:number = 2;
}

根据浏览器的不同,您可能会看到这些css属性,这就是为什么我添加了更常见和更旧的z-index,因此您可以看到可以使用模板内ngFor的索引变量动态呈现css值

我希望这有帮助!