Home > Software engineering >  How do you pass a function as an input via downgraded component for an angular hybrid app?
How do you pass a function as an input via downgraded component for an angular hybrid app?

Time:06-24

In angularJS, a directive allowed you to do:

angular.module('Directives').directive('myButton', [() => {
  return {
    restrict: 'E',
    template: '<button ng-click="callback()"></button>',
    bindings: { callback: '&' },
  };
}]);

and use it like:

<my-button callback="someCallback"></my-button">

# controller:
scope.someCallback = () => { alert('hi'); };

...

When I replace that directive with a modern angular component:

@Injectable({ providedIn: 'root' })
@Component({
  selector: 'my-button',
  template: '<button (click)="click()"></button>'
})
export class MyButtonComponent {
  @Input() callback: () => void;

  click () {
    this.callback();
  }
}

This works fine when I use it in modern Angular like:

@Injectable({ providedIn: 'root' })
@Component({
  selector: 'wrapper',
  template: '<my-button [callback]="someFunc"></my-button>'
})
export class WrapperComponent {
  someFunc: () => void;
  constructor() {
    this.someFunc = () => { alert('hi'); }
  }
}

... However, if I downgrade that component for a hybrid app:

angular.module('Directives').directive('myButton', downgradeComponent({ component: MyButtonComponent }))

And then try to use this in angularJS, the callback input gets a string value someCallback rather than passing the actual function into the component...

The only way I can figure out how to get this to work is to use an output and emit...

export class MyButtonComponent {
  @Output() callback = new EventEmitter();

  click () {
    this.callback.emit();
  }
}

And then use it like:

<my-button (callback)="someFunc()"></my-button>

Is there a way to tell the downgraded component that the input has a '&' binding so that I don't have to use an output AND thus have to change the markup for all my angularJS templates that used the directive?

CodePudding user response:

How are you using this directive in template?

You should use this new Angular way:

<my-button [callback]="someFunc"></my-button>

instead of:

<my-button callback="someFunc"></my-button>

Brackets are mandatory with downgraded component, otherwise it's like passing string to Angular 2 component.

  • Related