Reputation: 2399
I would like to specify default value for signal input that is based on other signal input. This is what I tried:
import { Component, input } from '@angular/core';
@Component({
selector: 'my-input',
standalone: true,
template: `
<input
type="number"
[min]="min()"
[max]="max()"
[value]="value()"
>
`,
})
export class MyInput {
min = input(0);
max = input(100);
value = input<number | undefined, number>(undefined, {
transform: (value) => value || this.min(),
});
}
But transform
function is not even triggered.
To force transform
function trigger i have to pass some value to the component:
<my-input [value]="undefined" />
Is it possible to make it work without passing undefined
?
Upvotes: 1
Views: 3287
Reputation: 57721
We can also use a computed signal to limit the range or perform any transformations like how we do with transform!
child
import { Component, computed, input } from '@angular/core';
@Component({
selector: 'my-input',
standalone: true,
imports: [],
template: `
<input
type="number"
[min]="min()"
[max]="max()"
[value]="limitedValue()"
>
{{min()}}
`,
styleUrl: './test.component.css',
})
export class TestComponent {
min = input<number>(0);
max = input<number>(100);
value = input<number>();
limitedValue = computed(() => {
const max = this.max(),
min = this.min(),
value = this.value() || min;
return value > max ? max : value < min ? min : value;
});
}
parent
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { TestComponent } from './app/test/test.component';
@Component({
selector: 'app-root',
standalone: true,
imports: [TestComponent, FormsModule],
template: `
<my-input />
<my-input [value]="value" [min]="5"/>
<my-input [value]="5" [min]="5"/>
<br/> changing input <input [(ngModel)]="value"/>
`,
})
export class App {
value = 0;
name = 'Angular';
}
bootstrapApplication(App);
this below code does not work when min
gets set, go for first one!
I would just set min as the default value of the signal, then I am guessing you want to limit the input value within a range, so we can apply that logic on the transform using comparison operators!
Child:
import { Component, input } from '@angular/core';
@Component({
selector: 'my-input',
standalone: true,
imports: [],
template: `
<input
type="number"
[min]="min()"
[max]="max()"
[value]="value()"
>
`,
styleUrl: './test.component.css',
})
export class TestComponent {
min = input(0);
max = input(100);
value = input<number | undefined, number>(this.min(), {
transform: (value) => {
const max = this.max(),
min = this.min();
return value > max ? max : value < min ? min : value;
},
});
}
Parent:
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { TestComponent } from './app/test/test.component';
@Component({
selector: 'app-root',
standalone: true,
imports: [TestComponent],
template: `
<my-input />
<my-input [value]="1000"/>
<my-input [value]="1000"/>
`,
})
export class App {
name = 'Angular';
}
bootstrapApplication(App);
Upvotes: 1