1

In Angular4, property binding on the view (.html) picks up the value from the logic file (.ts)

This works well in the code:

<img [src]="sourceValue"> 

This too works well in the code:

<button [disabled]="isDisabled"> 

Why does this not work?

<p [style]="paragraphStyle"> This is a paragraph.</p>

abc.component.ts

isDisabled:boolean = true; 
sourceValue:string = "./assets/hermione.jpg"; 
paragraphStyle:string = "background:red; color:yellow";

I know the usage of ngStyles and ngClass, I simply want to ask why property binding is not working in the above case. It is finally --- just a simple "Inline CSS Styling" if value is taken from .ts file and added to the html snippet in front of 'style' property in paragraph.

1
  • 1
    You are doing things here that you shouldn't, your TypeScript file in a component is for marshalling data between the html view and services and the html file is for presentation. If you have image names and styles in your TypeScript then you are thinking about the separation of concerns incorrectly. Commented Sep 16, 2018 at 1:00

2 Answers 2

2

It's because of security Measures:

@Angular docs
Angular defines the following security contexts:

  • HTML is used when interpreting a value as HTML, for example, when
    binding to innerHtml.
  • Style is used when binding CSS into the style property.
  • URL is used for URL properties, such as <a href>.

  • Resource URL is a URL that will be loaded and executed as code, for example, in <script src>.

The Fix is to sanitize values beforehand using bypassSecurityTrustStyle()- Bypass security and trust the given value to be safe style value (CSS).

@Angular docs

WARNING: calling this method with untrusted user data exposes your application to XSS security risks!

Component:

import { Component, SecurityContext } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';
  paragraphStyle;
constructor(private _sanitizer: DomSanitizer){ 

  this.paragraphStyle=this._sanitizer.bypassSecurityTrustStyle("background-color:red");
}

HTML

<p [style]="paragraphStyle"> This is a paragraph.</p>

NOTE:

For style property name use dash-case. For example, font-weight ,background-color

Live Demo

Sign up to request clarification or add additional context in comments.

Comments

1

I think you can do it but you have to do it like so: [style.background]="'red'"

6 Comments

Thanks, but the question again stucks, why not just picking up value from .ts and replacing like other cases on view part? It would be a 'simple inline styling'.
Dunno but I know that it doesn't really work the way you want it has to do something with styling rules and how they apply them within Renderer. Best is just to use ngStyles or ngClass. Btw you should prefer using classes instead since inline styles don't cache in browser.
And with this method you can actually pick up the value from ts you just need to replace 'red' with property name. Like so: [style.background]="redVariable"
Are you getting any errors or warings? "Technically, Angular is matching the name to a directive input, one of the property names listed in the directive's inputs array or a property decorated with @Input(). Such inputs map to the directive's own properties." --> "If the name fails to match a property of a known directive or element, Angular reports an “unknown directive” error."
@NerijusPamedytis Have a look at my answer to get a clear picture:)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.