Best way to handle a semi-common header, footer, and side menu

5,255 views
Skip to first unread message

Ryan Zec

unread,
Dec 15, 2012, 11:00:23 AM12/15/12
to ang...@googlegroups.com
I am trying to figure out the best way right now with the way routes and views work to handle an application that is going to have a semi-common header, footer, and side menu.  What I mean by semi-common is that most pages will share between a few different headers, footers, and side menu and the data in them might be slight different however the basic HTML structure is going to be the same.  Right now all 3 elements are being defined in the rootScope as variables that store the part to the template.  This way I can have a default value but each controller can override if needed.  There are one issues with this however:

1.  Each template contains the same basic structure for including the header, footer, and side menu.  These elements needs to have access to the scope for data which from my understanding, means that it needs to be inside the ngView (ie. I can't puut that structure into the index.html).
2.  The header, footer, and side menu are being re-render everytime I switch pages (again, because it is part of the template for each page.

Now the idea I have to solve the first issue (have not tested this out yet) is when defining my route, every route will use the same template and then evey controller will define the path to the page specific template.  This way I only write the basic layout HTML once and then include the page specific HTML through an include in the main layout template.  Is this the best way to handle this issue or is there another solution that might be better?

The second problem I imagine would still exist.  Is there currently a way to tel AngularJS to only re-render part of a view instead of the whole things?

Witold Szczerba

unread,
Dec 15, 2012, 4:59:48 PM12/15/12
to ang...@googlegroups.com

Hi,
I would define the static layout in main html template (index.html most ogre the time) and use the ng-include directives for semi-common elements. Then, the ng-view for the main section which depends on $route service.

Regards,
Witold Szczerba
---
Sent from my mobile phone.

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en-US.
 
 

Ryan Zec

unread,
Dec 15, 2012, 5:06:41 PM12/15/12
to ang...@googlegroups.com
Well the thing is that the layout it not static, it requires access to the scope in order to properly display information (the user's name in the header; whether or not the side menu should even shown and if it does, what items to show; heck, some pages might have a completed different header than other pages). 

Witold Szczerba

unread,
Dec 15, 2012, 6:35:29 PM12/15/12
to ang...@googlegroups.com
Correct me if I am wrong, but your layout is static: you always have a
header, footer, side menu and main section. So your index.html may
look like this:
<div ng-include="layout.header"></div>
<div ng-include="layout.menu"></div>
<div ng-view></div>
<div ng-include="layout.footer"></div>

Come up with your own "layout" service. It's role (also
implementation) is simple: to maintain the header, menu and footer
properties. Put the instance of that service to the scope accessible
by your ng-include directives, propably $rootScope (it is possible not
to pollute the scope, but it is not important right now). Your layout
service will be to your header, menu and footer what $route and it's
provider are for ng-view.

Regards,
Witold Szczerba

Andy Czerwonka

unread,
Dec 16, 2012, 1:24:21 AM12/16/12
to ang...@googlegroups.com
Can anyone point to an example?

Ryan Zec

unread,
Dec 19, 2012, 8:49:50 AM12/19/12
to ang...@googlegroups.com
Witold,

Well now it seems to be working fine even though either it was not (maybe something in my refactoring fixed it).  You mentioned I could do this not polluting the scope so I would be curious to how?


Thanks,
Ryan Zec

On Sun, Dec 16, 2012 at 1:24 AM, Andy Czerwonka <andy.cz...@gmail.com> wrote:
Can anyone point to an example?

Witold Szczerba

unread,
Dec 19, 2012, 12:53:33 PM12/19/12
to ang...@googlegroups.com
Hi,
you could implement it like this:
directive('layout', function(layout, $compile) {
return {
scope: true,
link: function(scope, element, attrs) {
scope.layout = layout;
var srcAttr = ' src="layout.' + attrs.layout +' " ';
element.append($compile('<div ng-include'+srcAttr+'></div>')(scope));
}
}
});

index.html:
<div layout="header"></div>
<div layout="menu"></div>
<div ng-view></div>
<div layout="footer"></div>

Did not try it, but should work fine.

Regards,
Witold Szczerba

Makarand Bhatamrekar

unread,
Oct 21, 2013, 2:47:11 PM10/21/13
to ang...@googlegroups.com
This is exactly what I want to do, but do not want the header and footer to appear on the login.html page,
how can I do it.

Kai Groner

unread,
Oct 21, 2013, 3:29:20 PM10/21/13
to ang...@googlegroups.com
A couple options: 

1. Use a router that supports named views.  ui-router and dotjem/angular-routing are two routers that support this.

2. Use ng-class at the root of your app to indicate if the user is authenticated, then use CSS to select which parts of the header should be visible.

I recently used 1. and switched to 2. because I was showing the same header most of the time.


Kai
 


To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.

To post to this group, send email to ang...@googlegroups.com.

Dmitri Akatov

unread,
Oct 27, 2013, 9:07:19 PM10/27/13
to ang...@googlegroups.com
Hi there, I had a similar problem recently, and I came up with the following rudimentary solution:

https://gist.github.com/akatov/7189341
http://plnkr.co/edit/gist:7189341?p=preview  to see it in action

I wanted to minimize the number of html files / templates I'd need so with my layout directive you can layout files

e.g. layout1.html:
<ul>
  <li> <yield content_for="fst"/></li>
  <li> <yield content_for="snd"/></li>
</ul>

and layout2.html:
<table><tr>
  <td> <yield content_for="fst"/></td>
  <td> <yield content_for="snd"/></td>
</div>


and then your actual views would use the layout template(s) like this:

file1.html:
<div ng-controller...>
  <layout src="layout1.html">
    <div content_for="fst">
       this can contain arbitrary contents including subtags and directories
    </div>

   <div content_for="snd">
      {{ user }}
   </div>
  </layout>
</div>


this may not be quite as flexible as an implementations using ui.router and a sophisticated nesting of partial views according to a particular application state for instance, but it is pretty straightforward and i think requires a minimal amount of html templates, since a layout can contain as many yield tags as you need.

I wanted to see whether anybody else would find this useful, and whether I should try to make a proper library out of it and clean up the code, write some tests etc.

Thanks

as...@holidaysimply.com

unread,
Mar 10, 2016, 1:50:42 AM3/10/16
to AngularJS, pljos...@gmail.com
Hi,

Can u post an example.
Reply all
Reply to author
Forward
0 new messages