Reputation: 2207
I have been struggling to figure out the best way to dynamically change the background-image
attribute in a number of Angular 2 components.
In the following example, I am attempting to set the background-image
of a div to an @Input
value using [ngStyle]
directive:
import {Component, Input} from '@angular/core';
import { User } from '../models';
// exporting type aliases to enforce better type safety (https://github.com/ngrx/example-app)
export type UserInput = User;
@Component({
selector: 'profile-sidenav',
styles: [ `
.profile-image {
background-repeat: no-repeat;
background-position: 50%;
border-radius: 50%;
width: 100px;
height: 100px;
}
`],
template: `
<div class="profile-image" [ngStyle]="{ 'background-image': url({{image}})">
<h3>{{ username }}</h3>
`
})
export class ProfileSidenav {
@Input() user: UserInput;
blankImage: string = '../assets/.../camera.png';
// utilizing "getters" to keep templates clean in 'dumb' components (https://github.com/ngrx/example-app)
get username() {
return this.user.username;
}
get image() {
if (!this.user.image) { return this.cameraImage;
} else { return this.user.image; }
}
I don't think the issue is with the observable, since username
displays and doing something like <img *ngIf="image" src="{{ image }}">
renders the image. I have to access the background-image
attribute because apparently that is the best way to make a circular image, but in general would like to know how to do this.
EDIT:
My original [ngStyle]
declaration had unnecessary curly brackets (ngStyle is a directive that can take a variable), and was missing string tags around url()
and image
. The correct way is (as answered below) is:
<div class="profile-image" [ngStyle]="{'background-image': 'url(' + image + ')'}"></div>`.
As stated in the original edit, a solution can also be achieved with the Renderer class in Angular 2. I have yet to do it but think there should be a way with setElementStyles
or something like that. I will try to post an example but would love if someone else showed me (and others) how to for the time being.
Upvotes: 47
Views: 79331
Reputation: 355
I encountered this same issue and came up with a solution that works for image paths which contain spaces.
Within your component's HTML, add the style as follows where _imageBGPath is a property of your component.
Component HTML
<div [style.background-image]="'url(' + _imageBGPath + ')'">
...
</div>
Within your component declaration, add an input property so that we can run encodeURI on the supplied value to account for spaces.
Component Declaration
@Component({
selector: 'image-display',
templateUrl: './imageDisplay.component.html',
styleUrls: ['./ImageDisplay.component.css'],
providers: []
})
export class ImageDisplayComponent {
@Input() set imageBGPath(value: string | undefined) {
if (value != undefined && value != null) {
this._imageBGPath = encodeURI(value);
}
};
public _imageBGPath: string = "";
constructor() {
}
}
Now when you reference your component, you can supply the path to your image. If supplying inline with the component then you need to enclose it with '' so that angular knows this is a string being supplied and not a variable.
<image-display [imageBGPath]="'assets/Image With Spaces.jpg'"></image-display>
Upvotes: 0
Reputation: 812
redfox05's answer works well since there is no space in the image URL, but by a bit change in code we can make it work again:
<div style.background-image="url('{{image}}')"></div>"
Upvotes: 3
Reputation: 3672
You don't need to use NgStyle
. You can also do this:
[style.background-image]="'url(' + image + ')'"
See more at How to add background-image using ngStyle (angular2)?
Upvotes: 43
Reputation: 21
The main reason is simple, you declared a global variable as blankImage
but in the template you called image
instead of blankImage
.
Your ts code variable blankImage
blankImage: string = '../assets/.../camera.png';
Your template code variable image
<div class="profile-image" [ngStyle]="{'background-image': 'url(' + image + ')'}"></div>
Upvotes: 2
Reputation: 745
that's wrong
I think you should add:
<div class="profile-image" [ngStyle]="{ 'backgroundImage': url({{image}})">
Regards
Upvotes: -3
Reputation: 202196
I think that you should use something like that:
<div class="profile-image"
[ngStyle]="{ 'background-image': 'url(' + image + ')'}">
where image
is a property of your component.
See this question:
Upvotes: 85