简体   繁体   中英

Angular 1.5 passing a function with parameters to a component?

I have a session service like follows with two methods representing two ways of authenticating:

angular
  .module('myApp')
  .service('sessionService', SessionService);

function SessionService() {
  var $ctrl = this;

  this.logInTypeA = function(username, password, authenticator) {
    ...
  }

  this.logInTypeB = function(username, password, authenticator) {
    ...
  }

  ...
}

I have a log in form component. I would like to have two instances of the form which use the two different log in methods but are otherwise the same:

<log-in-form log-in-method="$ctrl.sessionSerive.logInTypeA"></log-in-form>
<log-in-form log-in-method="$ctrl.sessionSerive.logInTypeB"></log-in-form>

The component's JS looks something like this:

angular
  .module('myApp')
  .component('logInForm', {
    templateUrl: 'app/components/log-in-form.template.html',
    controller: LogInFormController,
    bindings: {
      logInMethod: '&'
    }
  });

function LogInFormController() {
  var $ctrl = this;

  this.username = '';
  this.password = '';
  this.authenticator = '';

  this.logIn = function() {
    $ctrl.logInMethod($ctrl.username, $ctrl.password, $ctrl.authenticator);
  };

  ...
}

However, I get an error when I try to run this:

TypeError: Cannot use 'in' operator to search for '$ctrl' in testloginemail@example.com

How do I pass a method in a service to a component?

Thanks in advance.

Your HTML has a typo in the name of the service. Here is how I do this in Angular 1.4.x.

In the HTML, you should add the parameters of the function being called:

<log-in-form log-in-method="$ctrl.sessionService.logInTypeA(username, password, authenticator)"></log-in-form>
<log-in-form log-in-method="$ctrl.sessionService.logInTypeB(username, password, authenticator)"></log-in-form>

For the component, you need to add curly braces around the parameters and add each parameter name:

angular
  .module('myApp')
  .component('logInForm', {
    templateUrl: 'app/components/log-in-form.template.html',
    controller: LogInFormController,
    bindings: {
      logInMethod: '&'
    }
  });

function LogInFormController() {
  var $ctrl = this;

  this.username = '';
  this.password = '';
  this.authenticator = '';

  this.logIn = function() {
    $ctrl.logInMethod({username: $ctrl.username,
                       password: $ctrl.password,
                       authenticator: $ctrl.authenticator});
  };
  ...
}

If you want the code to use service functions by name:

<log-in-form log-in-method="logInTypeA"></log-in-form>
<log-in-form log-in-method="logInTypeB"></log-in-form>

Use attribute @ binding, and inject the service in the component:

app.component('logInForm', {
    templateUrl: 'app/components/log-in-form.template.html',
    controller: LogInFormController,
    bindings: {
      logInMethod: '@'
    }
});

function LogInFormController(sessionService) {
  var $ctrl = this;

  this.username = '';
  this.password = '';
  this.authenticator = '';

  this.logIn = function() {
    var method = sessionService[$ctrl.logInMethod];
    method($ctrl.username, $ctrl.password, $ctrl.authenticator);
  };

  ...
}

Use property accessor bracket notation to select the desired service method by name.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM