Amit
Amit

Reputation: 6294

AngularJS - What is the right way for this?

I created a page, in which you can view lots of details on a user, in panels.

Every panel contains some information, received from a service, and sometimes has actions on it.

I have about 10 panels, and the viewer decides what he wants to see.

Is it right to make each of those panels a separate controller, OR only panels with actions need to be in a separate controller, OR all the panels in one controller?


If every panel is a controller, and my code is this:

div class="panel panel-default">
  <div class="panel-heading">Panel Heading</div>
  <div class="panel-body" ng-controller="historyPanel" ng-include="'panels/history.html'"></div>
</div>

Is there a way for me to know if a panel is empty?

For example, I have an history panel, that I wanna show only when there is history to show, and I don't wanna show "No History", just wanna hide that panel.

But I do want to keep the panel code outside of the history.html view.

Upvotes: 0

Views: 47

Answers (2)

alphapilgrim
alphapilgrim

Reputation: 3975

Try something like this, try not to inject $scope at all cost. :)

function PanelCtrl() {
  'use strict';

  var ctrl = this;

  ctrl.panels = [{
    "id": 0,
    "name": "Lucia Oconnor",
    "history": "my history"
  }, {
    "id": 1,
    "name": "Stevenson Mcintosh",
    "history": "my history"
  }, {
    "id": 2,
    "name": "Spears Sims",
    "history": "my history"
  }];

}

function panel() {
  'use strict';

  return {
    restrict: 'E',
    scope: {},
    bindToController: {
      //Depends what youd like to do with the PanelCtrl
      //'&': use a function on that ctrl
      //'=': two way data binding
    },
    controller: 'PanelCtrl as ctrl',
    templateUrl: './templates/panel.ng.html'
  };
}

angular
  .module('app', [])
  .controller('PanelCtrl', PanelCtrl)
  .directive('panel', panel);

This would be that template:

   //also if static content might want to use--one time bindings.
   // that would be ::panel.name
  <div class="panel panel-default" id="panel_{{panel.id}}">
    <div class="panel-heading">{{Panel.name}}</div>
    <div class="panel-body">{{Panel.history}}</div>
  </div>

This would be your html:

  //be sure to include track by, major perf gains.
 <div class="container" ng-repeat="panel in ctrl.panels track by panel.id">
    <panel bind="here" ng-if="ctrl.history.length"></panel>
 </div>

Upvotes: 1

Dr. Cool
Dr. Cool

Reputation: 3721

You should consider creating a directive for this. You can either create a single directive that contains all 10 panels, and provide an attribute to specify which panel to show, or you could create 10 different directives.

Something like:

<my-panel panel="history" ng-show="userPanel.history.display"></my-panel>
<my-panel panel="settings" ng-show="userPanel.settings.display"></my-panel>
<my-panel panel="friends" ng-show="userPanel.friends.display"></my-panel>
<my-panel panel="music" ng-show="userPanel.music.display"></my-panel>

Then your scope controller might have something like:

app.controller('MyController', function($scope) {
    $scope.userPanel = {
        history: { display: true },
        settings: { display: true },
        friends: { display: true },
        music: { display: false }
    }
});

This way, you could load data from a service which has the user preferences for which panels are displayed.

Upvotes: 2

Related Questions