Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): add ability to transform input values #50420

Closed
wants to merge 1 commit into from

Commits on May 25, 2023

  1. feat(core): add ability to transform input values

    According to the HTML specification most attributes are defined as strings, however some can be interpreted as different types like booleans or numbers. [In the HTML standard](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes), boolean attributes are considered `true` if they are present on a DOM node and `false` if they are omitted. Common examples of boolean attributes are `disabled` on interactive elements like `<button>` or `checked` on `<input type="checkbox">`. Another example of an attribute that is defined as a string, but interpreted as a different type is the `value` attribute of `<input type="number">` which logs a warning and ignores the value if it can't be parsed as a number.
    
    Historically, authoring Angular inputs that match the native behavior in a type-safe way has been difficult for developers, because Angular interprets all static attributes as strings. While some recent TypeScript versions made this easier by allowing setters and getters to have different types, supporting this pattern still requires a lot of boilerplate and additional properties to be declared. For example, currently developers have to write something like this to have a `disabled` input that behaves like the native one:
    
    ```typescript
    import {Directive, Input} from '@angular/core';
    
    @directive({selector: 'mat-checkbox'})
    export class MatCheckbox {
      @input()
      get disabled() {
        return this._disabled;
      }
      set disabled(value: any) {
        this._disabled = typeof value === 'boolean' ? value : (value != null && value !== 'false');
      }
      private _disabled = false;
    }
    ```
    
    This feature aims to address the issue by introducing a `transform` property on inputs. If an input has a `transform` function, any values set through the template will be passed through the function before being assigned to the directive instance. The example from above can be rewritten to the following:
    
    ```typescript
    import {Directive, Input, booleanAttribute} from '@angular/core';
    
    @directive({selector: 'mat-checkbox'})
    export class MatCheckbox {
      @input({transform: booleanAttribute}) disabled: boolean = false;
    }
    ```
    
    These changes also add the `booleanAttribute` and `numberAttribute` utilities to `@angular/core` since they're common enough to be useful for most projects.
    
    Fixes angular#8968.
    Fixes angular#14761.
    crisbeto committed May 25, 2023
    Copy the full SHA
    d4641ad View commit details
    Browse the repository at this point in the history