How to add dynamic buttons per loaded page?

Asked

Viewed 27 times

0

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

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

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

export default AgenciesListController;

A Factory Action, simple, has the functions to add and grab all the buttons added:

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

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

export default ActionFactory;

I wish that when changing page, only show the buttons of the selected page, if a page has no buttons in its controller, nothing should be shown.

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

I must reset the array buttons every time you change page?

1 answer

0


The best solution and still with support for a future configuration is using a Provider. How I am using ui-router, I decided to put the dynamic button settings directly in the 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 looked 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 you keep the records of 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, the 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.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.