如何从 Angular 2 中的嵌套组件更改父背景图像?
How can you change a parent background image from a nested component in Angular 2?
对于我应用程序中的每个路由,我都需要更改父背景图像。我在每个嵌套组件中使用样式 属性 来实现此目的,在每个组件中将 ViewEncapsulation 设置为 None 以便它具有全局效果。这行得通,但问题是当我浏览应用程序时,我在 head 标签中获得了这种样式的多个实例:
<style>...</style>
<style>...</style>
子组件的代码如下:
import {Component, Output, EventEmitter} from '@angular/core';
import {ViewEncapsulation} from '@angular/core';
@Component({
selector: '',
templateUrl:'app/home.component.html',
styles: [`
.hero-unit {
background:url('/app/assets/images/hero-01.png');
width:100%;
height:540px;
background-size: cover;
background-repeat: no-repeat;
background-position: 50% 50%;
}
`],
encapsulation: ViewEncapsulation.None
})
export class HomeComponent {
}
一个覆盖另一个,这没关系,直到您尝试导航回上一页,效果停止工作。我的问题是,有没有一种方法可以在我离开该组件后删除样式 属性 并在我导航回来时将其重新插入。或者,有没有更好的方法来根据路线换出背景图像。我很难在 Angular 2 中找到完成如此简单任务的最佳方法。谢谢。
您可以使用路由器数据或服务。
路由器解决方案
将图片URL放入路由数据中:
{ path: 'child1',
component: Child1Component,
data: { imageUrl: '/app/assets/images/hero-02.png' }
}
然后父组件可以订阅路由事件,提取URL并更新样式属性:
import {Component, Renderer, ElementRef} from '@angular/core';
import {Router, ActivatedRoute, NavigationEnd} from '@angular/router';
@Component({
template: `<section>
UserComponent content here, if any.
<nav>
<a [routerLink]="['./']">Activity</a>
<a [routerLink]="['profile']">Profile</a>
- child routes
</nav>
<div class="child-view">
<router-outlet></router-outlet>
</div>
<section>`
})
export class UserComponent {
constructor(private router: Router, private route: ActivatedRoute,
private renderer:Renderer, private elref:ElementRef) {}
ngOnInit() {
this.router.events
.filter(event => event instanceof NavigationEnd)
.subscribe(_ => {
let childRouteSnapshot = this.route.firstChild.snapshot;
let url = childRouteSnapshot.data.imageUrl;
this.renderer.setElementStyle(this.elref.nativeElement.childNodes[0],
'background-image', 'url(' + url + ')');
})
}
}
这是一个有效的 Plunker。 (注意plunker中的部分代码只是半途转了RC5,上面展示的代码都是RC5。)
我不得不使用 childNodes[0]
因为在我的示例中 elref
被设置为 ng-component
而不是 <section>
.
服务解决方案
使用共享服务。请参阅食谱部分 Parent and children communicate via a service。子组件在父组件订阅的 observable/subject 上发布事件(即 URL 图像字符串)。
对于我应用程序中的每个路由,我都需要更改父背景图像。我在每个嵌套组件中使用样式 属性 来实现此目的,在每个组件中将 ViewEncapsulation 设置为 None 以便它具有全局效果。这行得通,但问题是当我浏览应用程序时,我在 head 标签中获得了这种样式的多个实例:
<style>...</style>
<style>...</style>
子组件的代码如下:
import {Component, Output, EventEmitter} from '@angular/core';
import {ViewEncapsulation} from '@angular/core';
@Component({
selector: '',
templateUrl:'app/home.component.html',
styles: [`
.hero-unit {
background:url('/app/assets/images/hero-01.png');
width:100%;
height:540px;
background-size: cover;
background-repeat: no-repeat;
background-position: 50% 50%;
}
`],
encapsulation: ViewEncapsulation.None
})
export class HomeComponent {
}
一个覆盖另一个,这没关系,直到您尝试导航回上一页,效果停止工作。我的问题是,有没有一种方法可以在我离开该组件后删除样式 属性 并在我导航回来时将其重新插入。或者,有没有更好的方法来根据路线换出背景图像。我很难在 Angular 2 中找到完成如此简单任务的最佳方法。谢谢。
您可以使用路由器数据或服务。
路由器解决方案
将图片URL放入路由数据中:
{ path: 'child1',
component: Child1Component,
data: { imageUrl: '/app/assets/images/hero-02.png' }
}
然后父组件可以订阅路由事件,提取URL并更新样式属性:
import {Component, Renderer, ElementRef} from '@angular/core';
import {Router, ActivatedRoute, NavigationEnd} from '@angular/router';
@Component({
template: `<section>
UserComponent content here, if any.
<nav>
<a [routerLink]="['./']">Activity</a>
<a [routerLink]="['profile']">Profile</a>
- child routes
</nav>
<div class="child-view">
<router-outlet></router-outlet>
</div>
<section>`
})
export class UserComponent {
constructor(private router: Router, private route: ActivatedRoute,
private renderer:Renderer, private elref:ElementRef) {}
ngOnInit() {
this.router.events
.filter(event => event instanceof NavigationEnd)
.subscribe(_ => {
let childRouteSnapshot = this.route.firstChild.snapshot;
let url = childRouteSnapshot.data.imageUrl;
this.renderer.setElementStyle(this.elref.nativeElement.childNodes[0],
'background-image', 'url(' + url + ')');
})
}
}
这是一个有效的 Plunker。 (注意plunker中的部分代码只是半途转了RC5,上面展示的代码都是RC5。)
我不得不使用 childNodes[0]
因为在我的示例中 elref
被设置为 ng-component
而不是 <section>
.
服务解决方案
使用共享服务。请参阅食谱部分 Parent and children communicate via a service。子组件在父组件订阅的 observable/subject 上发布事件(即 URL 图像字符串)。