angularangular2-directives

When to use square brackets [] in directives @Inputs and when not?


I'm confused a little. When to use square brackets [] in directives @Inputs and when not?

See this simple directive:

 @Directive({
      selector: '[myDirective]'
    })
    export class MyDirective {
    
      private text: string;
      private enabled: boolean;
    
      @Input() myDirective:string;
    
      @Input('myText')
      set myText(val: string) {
        this.text = val;
      }
    
      @Input('myEnabled')
      set myEnabled(val: boolean) {
        this.enabled = val;
      }
    
      ngOnInit() {
     
        console.log("myDirective string: " + this.myDirective);
        console.log("myText string: " + this.text); 
        console.log("myEnabled boolean: " + this.enabled);
    }
}

If my HTML will look like this:

<div [myDirective]="myDefaultText" [myEnabled]="true"  [myText]="abc"></div>

The output will be:

myDirective string: myDefaultText real value  // good
myEnabled boolean: true                       // good
myText string: undefined                      // Why?

If I remove the [] from myText:

<div [myDirective]="myDefaultText" [myEnabled]="true"  myText="abc"></div>

The output will be:

myDirective string: myDefaultText real value  // good
myEnabled boolean: true                       // good
myText string: abc                            // GOOD

I can also remove the [] from myEnabled and it will work too.

So, here is my confusion - when I need to use square brackets [] and when not, while I want the user, who is going to use myDirective, will never need to wonder if or if not, I think the square brackets [] should always be there. Aren't they?


Solution

  • When you use [] to bind to an @Input(), it's basically a template expression.

    The same way displaying {{abc}} wouldn't display anything (unless you actually had a variable called abc).

    If you have a string @Input(), and you want to bind it to a constant string, you could bind it like this: [myText]=" 'some text' ", or in short, like a normal HTML attribute: myText="some text".

    The reason [myEnabled]="true" worked is because true is a valid template expression which of course evaluates to the boolean true.