简体   繁体   English

使用Renderer和ElementRef修改组件

[英]Modify component with Renderer and ElementRef

1 ISSUE 1问题


I am trying to implement the following: 我正在尝试实现以下内容:

I have a container component ContainerComponent and child components ChildComponent . 我有一个容器组件ContainerComponent和子组件ChildComponent I want to modify the rendering and overall behaviour of the child components via the controlling ContainerComponent . 我想通过控制ContainerComponent修改子组件的呈现和整体行为。


2 TECHNOLOGIES USED 2技术使用


Angular2 , HTML , CSS , Javascript , Typescript , ES6 Angular2HTMLCSSJavascriptTypescriptES6


3 CODE 3代码


ContainerComponent.ts 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 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 CODE EXPLANATION 4代码解释


In the above code, the ContainerComponent dynamically inserts ChildComponent s (granted, this could be done without the DynamicContentLoader ). 在上面的代码中, ContainerComponent动态插入ChildComponent (授予,这可以在没有DynamicContentLoader情况下完成)。

The ChildComponents should dynamically add css properties, in this case, the animation delay once it is displayed. ChildComponents应该动态添加css属性,在这种情况下,一旦显示动画延迟。 So based on the index of the child, the animation delay increases. 因此,基于孩子的索引,动画延迟增加。

However the modifications from the renderer do not take effect, the css properties are not there at runtime. 但是,渲染器的修改不会生效,css属性在运行时不存在。

I tried to reproduce your problem. 我试图重现你的问题。 In fact, I have problem to add styles like -webkit-animation-delay and animation-delay . 事实上,我有问题添加像-webkit-animation-delayanimation-delay这样的样式。

If I try with another style like color , it works fine and the style is taken into account at runtime. 如果我尝试使用其他类似color样式,它可以正常工作,并且在运行时会考虑样式。

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

So it seems to be linked to animation styles... I see these links that could interest you: 所以它似乎与动画风格有关......我看到这些链接可能让你感兴趣:

Otherwise it seems that there is some support for animation in Angular2 but it's not really documented... See this file: https://github.com/angular/angular/blob/master/modules/angular2/src/animate/animation.ts . 否则似乎在Angular2中有一些动画支持,但它没有真正记录...请参阅此文件: https//github.com/angular/angular/blob/master/modules/angular2/src/animate/animation。 ts

Hope it helps you, Thierry 希望它对你有帮助,蒂埃里

This seems to be a bug in angular2 itself. 这似乎是angular2本身的一个错误。 Adding !important to a style will result in an illegal value to the style and it is not applied to the element. 在样式中添加!important将导致样式的非法值,并且不会应用于该元素。 The correct way in plain js is to use another parameter which implies if the style is important. 普通js中的正确方法是使用另一个参数,这意味着样式是否重要。

So the correct answer is to use: 所以正确答案是使用:

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

and if you want to add !important you have to use: 如果你想添加!important你必须使用:

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

The -webkit- prefix gets added (or removed) if necessary, so there is no need to add that as well 如有必要,会添加(或删除) -webkit-前缀,因此也不需要添加它

From here: 从这里:

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

You should only use ElementRef as an absolute last resource. 您应该只使用ElementRef作为绝对的最后资源。 The whole idea of Angular 2 is that you don't have to mess with the dom at all. Angular 2的整个想法是你根本不必弄乱dom。 What you are trying to do can be acomplished very easy using a template: 使用模板可以很容易地完成您想要做的事情:

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;
}

Depending on the browser you might see those css properties or not, that's why I added the z-index which is more common and old so you can see you can render the css value dynamically using the index variable from ngFor inside a template. 根据浏览器的不同,您可能会看到这些css属性,这就是为什么我添加了更常见和更旧的z-index,因此您可以看到可以使用模板内ngFor的索引变量动态呈现css值。

I hope this helps ! 我希望这有帮助 !

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM