How to add dynamic buttons per page loaded?

0

My controller calls factory Action and adds buttons on the page I'm loading, see below controller:

class AgenciesListController {
  /* @ngInject */
  constructor(Action) {
    this.action = Action;

    this.action.addButton({
      title: 'Nova Agência',
      state: 'agencies.new'
    });
  }
}

export default AgenciesListController;

The factory Action , simple, has the functions of adding and catching all the buttons added:

const ActionFactory = () => {
  let buttons = [];

  return {
    addButton: (button) => buttons.push(button),
    getButtons: () => buttons
  };
};

export default ActionFactory;

I want to change the page, just display the buttons on the selected page, if a page does not have buttons in its controller, nothing should be displayed.

The code above causes unwanted behavior by adding new buttons every time the page is selected from the menu.

Should I reset the buttons array every time I change pages?

    
asked by anonymous 20.10.2016 / 18:49

1 answer

0

The best solution and still support for a future configuration is using a Provider. As I'm using ui-router , I decided to put the dynamic button settings directly in route creation, see an example:

.state('agencies.list', {
  url: '/list',
  component: 'agenciesList',
  data: {
    action: {
      buttons: [{
        title: 'Nova Agência',
        state: 'agencies.new'
      }]
    }
  },
  resolve: {
    /* @ngInject */
    agencies: Api => Api.all('agencies').getList()
  }
})

The component controller looks like this:

import { registerListenerOnce } from './action.utils.js';

class ActionController {
  /* @ngInject */
  constructor($action, $rootScope) {
    this.action = $action;
    this.scope = $rootScope;
  }

  $postLink() {
    const renderAction = () => {
      this.buttons = this.action.getButtons();
    };

    registerListenerOnce('ActionDirective.$viewContentLoaded', this.scope, '$viewContentLoaded', () => {
      renderAction();
    });

    renderAction();
  }
}

export default ActionController;

I created a class utils where it has the records of the listeners :

let $registeredListeners = {};

const registerListenerOnce = (tag, $rootScope, event, fn) => {
  let deregisterListenerFn = $registeredListeners[tag];

  if (deregisterListenerFn !== undefined) {
    deregisterListenerFn();
  }

  deregisterListenerFn = $rootScope.$on(event, fn);
  $registeredListeners[tag] = deregisterListenerFn;
};

export {
  registerListenerOnce
};

And most importantly, provider :

class ActionProvider {
  /* @ngInject */
  $get($state) {
    return {
      getButtons: () => {
        let current = $state.$current;
        let buttons = null;

        if (current.data.action) {
          buttons = current.data.action.buttons;
        }

        return buttons;
      }
    };
  }
}

export default ActionProvider;

I hope to help other developers with this solution.

    
20.10.2016 / 21:55