Dynamically Adding Directives

97 views
Skip to first unread message

Jacob Valenta

unread,
Feb 21, 2014, 6:12:12 PM2/21/14
to ang...@googlegroups.com
I have been using AngularJS for a little while now, and we would like to design our app with it, but the design of the app is very difficult for me to picture in Angular.

Basically, the design is centered around panes (Think left to right, all panes are siblings) . We would like it so you can click a link in one pane, and a new pane will be created and filled with content.

Our software uses Customers, Items, Transactions and more. and we would like it to function more or less like this:

A Customer Pane is opened, showing details about the customer. In this pane, the customer's Items are listed. When the user clicks a specific Item, another pane is opened (Without closing the last one). On this new Item pane, there could be a link to the transaction, which would open another pane with the transactions. On this pane, the customer could be linked to again, which would open (A Second) Customer Pane.

My initial thoughts have been towards directives likes <pane></pane> <customer></customer>(for links to customers, which would open in new panes) <item></item>, and <transaction></transaction>

My question is how would I go about adding a new pane dynamically from these other directives?
(Also any warnings/pitfalls/insights about this design are welcome!)

Alesei N

unread,
Feb 22, 2014, 12:13:43 AM2/22/14
to ang...@googlegroups.com
I don't think you have to, if I understand you correctly, you can use either ng-if or ng-show. See documentation, but you could basically show these conditionally. NG-IF would be equivalent of conditional/dynamic rendering of any specific directive. NG-SHOW would basically set display:block on the parent element. 

Luke Kende

unread,
Feb 22, 2014, 2:27:56 AM2/22/14
to ang...@googlegroups.com
If I understand you correctly, I would do this with ng-repeat, since as you add or remove data to the array, it would create new panes (or items, or whatever).

<pane ng-repeat="pane in panes" style="float:left;>
  <customer="pane.customer"></customer>
  <item="item" ng-repeat="item in items">
    <transaction="item.transaction">
      <a ng-click="showCustomer(item.transaction.customer)">View Customer</a>
    </transaction>
  </item>
</<pane>

function MyCtrl($scope, MyService)
{
  $scope.panes = [
    { items: [ { transaction: { customer: 1 },  transaction: { customer: 3 }  } ] , customer: 5}, 
    { items: [ { transaction: { customer: 2 },  transaction: { customer: 4 }  } ] , customer 6 }
  ];

  $scope.showCustomer(customerId){
     var pane = MyService.getCustomer(customerId);
     $scope.panes.push(pane);

Jacob Valenta

unread,
Feb 22, 2014, 7:05:07 AM2/22/14
to ang...@googlegroups.com
Luke, I lose you at the <customer> directive. The contents of  a pane is what I am trying to load dynamically.

So 1 step is for the <pane> directive to retrieve the contents.
But 2, the contents of the pane will have directives (like <customer>) that must be compiled,

Am I correct?


--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/WHSBzWsle2k/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.



--
Jacob Valenta

Luke Kende

unread,
Feb 23, 2014, 4:44:44 AM2/23/14
to ang...@googlegroups.com
When you say "contents of the pane" ultimately that's a template bound to the scope for interpolation.

If you cannot know the contents of the pane and say your loading the html in via an http service, you would use $compile and inject into scope on the pane directive.... this is not the easy way.

My example was the case when you know the possible elements/directives that will display in the pane, hence customer directive is there but does not have to be shown until it's needed (use ng-if or ng-switch or ng-hide) same with any of the other directives and general elements in the pane's template.  

Again, the pane's template knows all possible conditions for what it could display and then shows what it needs based on logic in the scope.  This way does not require dynamically loading the template, but only dynamically showing what's needed.  Much easier.  With ng-repeat on pane you just push a new object to the array that defines what will be displayed and any data that is needed for those items:

$scope.panes.push({
  type: 'customer',
  customer: { name: 'Bob',  account: 12345, items:[] }
})
]
$scope.panes.push({
  type: 'item',
  item: { id: 123, price: '1.25' }
})

<pane ng-repeat="pane in panes" style="float:left;>

  <div ng-switch on="pane.type">

    <div ng-switch-when="customer">

      <customer="pane.customer" ></customer>
      <item-list="item" ng-repeat="item in items">
        <transaction="item.transaction">
          <a ng-click="showCustomer(item.transaction.customer)">View Customer</a>
        </transaction>
       </item-list>

    </div>

    <div ng-switch-when="item">
      <item='pane.item'></item>
    </div>

    <div ng-switch-when="transactions">
      <transaction-list ng-repeat="trans in transactions"></transaction-list >
    </div>

</<pane>










Reply all
Reply to author
Forward
0 new messages