Search code examples
angularjsangular-ui-routerdynamic-function

How to implement a dynamic function in Angular and UI-Router based on states?


Context:

I'm using Angular and ui-router...

I have a parent controller "ParentCtrl" with a template "ParentTempl".

Within the ParentTempl there is a view for 2 states: add and edit.

I want call a function from the ParentCtrl "abstractUpdate" that changes its behavior based on which state is active.

Current Code:

app.config(function($stateProvider, $urlRouterProvider) {
    $stateProvider
    .state('add', {
        template: "...", 
        abstractUpdate = function(object){
            // do add things
        }
    })
    .state('edit', {
        template: "...", 
        abstractUpdate = function(object){
            // do edit things
        }
    });
}

app.controller('ParentCtrl', function ($scope, $state) {
    $scope.click = function(obj){
        $state.current.abstractUpdate(obj);
    }
}

Question:

The current version is working, but you think it is the best solution? Any suggestions?


Solution

  • Usually you would use a factory or service for something like this. That way you don't clog up your routing with application logic. You could just inject $state into your factory/service so you can handle things based on the state you're in:

    angular.module('myApp').factory('MyService', [
        '$state',
        function ($state) {
          return {
            myMethod: function (obj) {
              if (this.hasOwnProperty($state.current.name)) {
                this[$state.current.name](obj);
              }
            },
            add: function (obj) {
              // do stuff
              return obj;
            },
            edit: function (obj) {
              // do stuff
              return obj;
            }
          }
        }
    ]);
    

    Now you can use your service from any controller you want, just inject it:

     angular.module('myApp').controller('myController', [
         '$scope',
         'MyService',
         function ($scope, MyService) {
             $scope.obj = {};
             $scope.obj = MyService.myMethod(obj);
         }
     ]);