admin管理员组

文章数量:1180551

In a app-test component I have the following:

  @Input( { transform: booleanAttribute})
  reverse: boolean = false;

  @HostBinding('style.flex-direction')
  direction: string = this.reverse ? 'column-reverse' : 'column';

And so if the designer applies the reverse attribute to app-test like this:

<app-test reverse></app-test>

Then Angular should set style="flex-direction: column-reverse" on the app-test element.

And I'm wondering how to use Angular signals so that when reverse is set to true, direction will be set to column-reverse. Thoughts?

In a app-test component I have the following:

  @Input( { transform: booleanAttribute})
  reverse: boolean = false;

  @HostBinding('style.flex-direction')
  direction: string = this.reverse ? 'column-reverse' : 'column';

And so if the designer applies the reverse attribute to app-test like this:

<app-test reverse></app-test>

Then Angular should set style="flex-direction: column-reverse" on the app-test element.

And I'm wondering how to use Angular signals so that when reverse is set to true, direction will be set to column-reverse. Thoughts?

Share Improve this question asked Feb 25, 2024 at 3:41 OleOle 46.9k68 gold badges236 silver badges440 bronze badges
Add a comment  | 

5 Answers 5

Reset to default 14

you can bind to host properties, attributes, classes, styles and events with host section of @Component decorator

host option is inherited from @Directive decorator, so you can use this technic also with directives

@Component({
  // ommited for brevity

  host: {
    // bind to classes
    'class': 'flex flex-col',
    '[class.active]': 'isActive()',   // <-- signal   

    // bind to some specific props
    '[tabIndex]': 'isDisabled() || isActive() ? -1 : 0',  // <-- also
    
    // bind to any attribute
    '[attr.aria-disabled]': 'isDisabled()',
    '[attr.aria-selected]': 'isActive()',

    // bind to style
    '[style.display]': 'isEnabled() ? "flex" : "none"',
    '[style.flex-direction]': 'isReversed() ? "column-reverse" : "column"',
    '[style.width]': 'progressSignal() + "px"' // expressions

    // bind css vars
    '[style.--component-color]': 'color()',

    // bind to events
    '(focus)': 'activateOption()', 
    '(click)': 'select($event)',

  }
})
export class SomeComponent {
  // ommited
}

This is being discussed in this issue. Currently the combination of @HostBinding and signals is not supported.

The workaround for this is to use a getter:

reverse = input.required<boolean>();

@HostBinding('attr.style.flex-direction')
get direction() { return this.reverse() ? 'column-reverse' : 'column' }

I would use an effect for that.

All these examples use a getter in the hostBinding but the thing with getters is that they're actually functions that will be executed every time change detection needs to "check" if the value has changed.

I would just do:

@Component({...})
public class MyComponent {
   public reverse = input<boolean>(false);
   @HostBinding('style.flex-direction') public reversedStyling = false;

   constructor(){
     effect(() => this.reversedStyling = this.reverse());
   } 
}

I'm sure the angular team will introduce a signal-based version of HostBinding and HostListeners sooner rather than later though.

You can do the following:

@Component({
  selector: 'app-child',
  standalone: true,
  template: 'My name (red is {{ red() }})',
})
export class AppChildComponent {
  red = input(false);

  @HostBinding('style.color')
  get color() {
    return this.red() ? 'red' : 'green';
  }
}

And in the container component:

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [AppChildComponent],
  template: `
    <app-child [red]="true"></app-child>
  `,
})
export class App {
}

Working example here

My current project was on Angular 16, so this is what I ended up with (Since input is for Angular 17+):

  @Input( { transform: booleanAttribute})
  reverse:boolean = false;

  @HostBinding('style.flex-direction')
  get direction() { return this.reverse ? 'column-reverse' : 'column' }

本文标签: javascriptUsing Angular Signals with HostBinding to update styleStack Overflow