Our SPA has 2 distinctive top level views. To compare it is like windows file explorer showing tree view on one side and content details on other side. For these top level views, we are considering to have 2 partial views. Other alternative is to pack these views as directives. Our initial thoughts are going toward partial views, because these are quite larger blocks of functionalties and each view can have multiple controllers. Any experience/thoughts on similar lines would help us decide. Just a note we communicate between these views using eventing mechanism.
We do not intend to reuses these views. Specifically, are there any issues going partial views? Like performance, maintainability, etc.
I'm not sure I'm understanding the problem here, so sorry if I say something wrong (also sorry for my english).
What you need are 2 views; if 'inside' those views you use a directive or not, it's another thing.
The only thing I'm pretty sure is that those 2 views need to have they're own scope.
To me it seems a lot like a 'navigation menu' vs. 'view' kind of problem (only that the navigation part is gonna be some sort of tree-view), so the solution should be similar:
the 'normal' ngView (your 'details' side);
a div with it's own controller (and it's own scope).
Something like:
<nav ng-controller="treeViewController()">
<!-- here we use a directive, for example -->
<tree-view ng-model="tree"></tree-view>
</nav>
<div ng-view></div>
Then the best way to make them communicate is probably a custom service.
In case I misunderstood your problem, sorry in advance.
Related
I am trying to learn and understand the capabilities of UI-router with Angular 1.3.15.
I am trying to set up an application which has many views that have a header and footer directive. It also has a smaller number of views that do not need this setup, with the loaded view taking up the entire page.
Therefore, it seems I should handle this divergence "one level down", as in my diagram below. In the past, I have worked on ui-router apps with the index.html coded with the header/footer directives and a single ui-view for the other pages to load into. This time I am trying to get it correct form the start. Opinions and advice welcome.
I'm not sure what you want to know.
Yeah, you should handle the difference in templates the way you suggested: the root template should contain only the elements which appear on all states. Elements which appear on some states should go on those states templates, in the template of a parent state (if it makes sense), or in directives that you reuse in the various templates.
Instead of directives, you might want to use named views if your templates have some peatures in common, but the differences between them are not inside a single DOM element. For example, maybe all your pages have a small toolbar on top that always has some buttons, but other buttons depend on the state you are in. You can place that constant part of the toolbar in the root template, together with a <div ui-view="toolbar"></div>. The states would then define a view named toolbar with a template with the buttons they want to add.
You could make a directive for that toolbar with all the global buttons in its template and use <ng-transclude> to add the custom buttons at each state's template, but using named views seems cleaner.
Just trying to understand the exact difference in approaches of using ngView and ngInclude in AngularJS. When would is it correct to use one over the other? Thanks.
ngView works together with routing, and is mostly essential to an angular SPA. It's normally used to include the main content of your site, the bit in between the header and footer that changes every time a user clicks a link. Its integration with routing means changing the ngView content changes the controller too (depending on your configuration).
ngInclude is a general purpose include, you may not even need it. You'd sometimes use it inside a view to avoid repeating yourself, in the cases where several views need the same code included.
I am using a master page having navigation and ng-view on it, partial pages loading successfully under ng-view and with navigation of master page , but I require to load some isolated page like login.html page but not under ng-view and without master page content during route.
I am new on angular and not sure how to do this, login page loaded every time under ng-view.
Please suggest me any way to do this.
Thanks in advanced.
ng-include is your friend. see doc
here is simple way, but you should go to doc and see that there are extra options as to what can be done onload and if you want to autoscroll or do some kind of animation.
<div ng-include="'somefile.html'">
</div>
The one extra note is that ng-include is given an expression so if you have a static reference you need the extra quotes.
One of the great things about Angular is it is very flexible. Ultimately it will depend on your app and how you work. I'm not exactly certain what you are trying to accomplish but, it sounds like a job for the ngInclude directive as Dan mentioned.
You mention a login.html that excludes navigational and other main page content. Using a modal may be a viable alternative interface decision.
If you have everything built and you only want to hide part of the DOM and be done with it then, nghide or ngShow may be the quickest solution.
If there is a lot of stuff on your index.html you may want to separate those things into partials other than the ones connected directly to your routes, and use ng-include="'path/to/partial.html'" to include them. (The "''" are intentional as it likes a string.) Read the docs and experiment with the plunkr. You can do a lot of cool things with ngInclude, especially if you pay attention to its context.
If you combine the ngInclude directive with ng-switch-when, you could put together something like:
<div ng-switch="routeAction">
<div ng-switch-when="extpage" ng-include="'extraneous.content.html'"></div>
<div ng-switch-when="login" ng-include="'login.partial.html'"></div>
<div ng-switch-default ng-include="'default.tpl.html'"></div>
</div>
Where routeAction is tied to your controler which, is tied to your $route or $location.. depending on how you have things set up.
I'm new to AngularJS, and - since it is quite complex and the approach is new for me, I'm a bit confused.
I'm from "classic" background (server-side template languages [like Yii, django, Smarty] + some jQuery to make things a bit dynamic).
Let's say I have a menu bar (Bootstrap NavBar, or anything else) - an element which lives outside of the main page content, like this:
<body>
<div id="menubar">
... <!-- menu content -->
</div>
<div class="container">
<div ng-view></div>
</div>
</body>
Now I'd like to make the menu a bit dynamic, i.e add or remove some menu items inside of the controller.
Using the server side frameworks & their templating systems, for example Yii - I'd simply have a BaseController class with $menuItems variable, and render it each time in the menuBar, while all the controllers would inherit from BaseController so they could modify items.
Also, I need a function which handles the searchForm located inside menu bar. Where should it live?
What is Angular way for something like this? So far I've been thinking of creating custom service or extending $rootScope.
UPDATE: I would encourage you to take a look at John Papa's ng-demoes and style-guide as say second step in adopting angular.js.
Check out examples angular.js team posted recently, to show full application.
github.com/IgorMinar/foodme
github.com/GoogleChrome/wReader-app
github.com/CaryLandholt/AngularFun
Pay attention to the following features angular gives you
ngView, ngInclude directives
templateUrl property of directive
'=', '&','#' scope bindings in directives
I belive it is going be a good approach to have combination of a service and a directive for rendering menu the way you described it.
My web application, written in Backbone.js, has what I call a number of "Modes".
Each mode describes which models and views that are currently active. By changing the mode parameter in the hash (#) I switch between modes and instantiate necessary Backbone models & views.
It seems logical to also describe the preferred layout and inject the container html code on a mode level.
Let's say the mode "PopulationPyramidMode" has a model and 3 Backbone views. The "HeaderView" should take up 30 pixels vertically. The "SidebarView" should take up 200 pixels horizontally and the "CanvasView" should fill moist of the screen and scale on resize events.
To complicate things further, the CanvasView holds a visualization which must be re-rendered on resize, i.e. the x/y-scales must be re-calculated.
So, what is the best approach to this?
1) Where should the layout logic go?
- On a separate layoutManager - and in that case how?
- Should each view describe its preferred size etc?
2) How do I inject the necessary HTML/CSS for my layouts and switch between them?
<!-- Layout 1 -->
<div id="header"></div>
<div id="sidebar"></div>
<div id="canvas"></div>
<!-- Layout 2 -->
<div id="header"></div>
<div id="canvas"></div>
Thanks for any specific hints and also on JavaScript layouts in general!
Just thinking out loud here. It sounds like you could have one view which manages the layout, but is capable of morphing the layout as needed. The question is: what triggers the layout change?
You might have a controller which is equipped with the routes and actions for these different modes. This controller could either hold an instance to this layout view and call a parameterized refresh function. Alternatively, the controller could trigger an event with the mode change and the view could be set up to listen for it. Once received, the view would call its refresh function.
My opinion regarding building such applications would be to use the straightforward observer pattern.
Design your controller in a way that it simply dispatches particular events when the hashtag changes. Have an event map in the controller,that acts as a reference table between events to be dispatched and the urls, better still, you can follow a particular convention regarding the choice of hash parts eg. everytime user navigates to url mydomain.com/#part1/part2 the controller dispatches an event 'evt_part1_part2'. You can use a common dispatch point (which can be a dom element, or a javascript object particularly being used for this very purpose).
Now all your views can listen to this common dispatch point, and if the event matches the one that this view is looking for, you can create the respective environment accordingly through that view.
This approach definitely helps in compartmentalization of views, leading of more modular and maintainable code.