How to dynamicaly change a ng-included view? - angularjs

I've the simplified following architecture:
<section ng-controller="myController">
<!-- Content -->
<button>Clic here !</button>
</section>
<aside ng-include="nav.html">
<!-- Content -->
</aside>
How can I dynamicaly change the view included into the aside tag when I clic on the button, driven by the myController controller?
Note that my controller's scope doesn't include the aside tag.

Set the ng-include to a variable on your scope.
<aside ng-include="currentTemplate">
<!-- Content -->
</aside>
add an ng-click to the button that calls a function to change this variable
<button ng-click="setTemplate()">Click here !</button>
Add the function and the variable to your controller:
$scope.currentTemplate = 'firstTemplate.html';
$scope.setTemplate = function(){
$scope.currentTemplate = 'clickedTemplate.html';
}
That should do it.
Fiddler example: http://jsfiddle.net/AU6Mr/1/

Related

How to share directive scope with transcluded elements?

I am trying to create a directive with transclusion. Issue is the scope of transcluded part is different from that of the directive scope.
I have tried it on plnkr here is the link - http://plnkr.co/edit/vDfXs9zyfAngPqmFCiZR?p=preview
I want the directive to have isolated scope yet be able to switch among the tabs, based on which button is clicked.
index.html
<maple-multistep-form steps="steps">
<span>transcluded scope - {{selection}}</span>
<div ng-switch="" on="selection">
<!-- First Step -->
<div ng-switch-when="Step 1: Team Info">
<ng-include src="'step1.html'"></ng-include>
</div>
<!-- Second Step -->
<div ng-switch-when="Step 2: Campaign Info">
<ng-include src="'step2.html'"></ng-include>
</div>
<!-- Third Step -->
<div ng-switch-when="Step 3: Campaign Media">
<ng-include src="'step3.html'"></ng-include>
</div>
</div>
Try passing the 'selection' to the directive.
http://plnkr.co/edit/23QO2UGvKwwXK7PRo2bJ?p=preview
<maple-multistep-form steps="steps" selection="selection">
and inside
scope: { //comment scope to make the directive have shared scope, this makes the directive work fine
steps: '=',
selection: '=?'
},

angular controllers, multiple templates, and passing scope values from controllers to master page

I'm starting a new project and am going to be using angular in a "single page architecture" application. I'm a little new to angular.
So, I purchased a template for my site. It has 2 distinct layouts that I would like to use. 1 for my unauthenticated (marketing) pages and another for most of my authenticated pages.
The difference in each is subtle, but the inside pages require a class on the <body> tags that the outside pages cannot have. I considered using 2 layouts but then that got tricky as I started thinking about how I would lay out my urls.
My thought is to use angular to manage my layout so that I only need one master page like this:
<body ng-class="{menu-right-hidden: isInternalPage }">
<div class="container-fluid">
<div ng-if="isInternalPage" id="menu" class="hidden-print hidden-xs sidebar-blue sidebar-brand-primary">
<!-- sidebar content -->
</div>
<div id="content">
#RenderBody()
</div>
<div class="clearfix"></div>
<div ng-if="isInternalPage" id="footer" class="hidden-print">
<!-- internal footer -->
</div>
<div ng-if="!isInternalPage" id="footer" class="hidden-print">
<!-- external footer -->
</div>
</div>
</body>
My question is this: Is there an easy way to set isInternalPage (and possibly other valies) without having $scope.isInternalPage = true/false; decorating all of my controllers?
You could use ng-init and define a scope variable on $rootScope:
<body ng-init="$root.isInternalPage = true" ng-class="{menu-right-hidden: $root.isInternalPage }">
<div class="container-fluid">
<div ng-if="$root.isInternalPage" id="menu" class="hidden-print hidden-xs sidebar-blue sidebar-brand-primary">
<!-- sidebar content -->
</div>
<div id="content">
#RenderBody()
</div>
<div class="clearfix"></div>
<div ng-if="$root.isInternalPage" id="footer" class="hidden-print">
<!-- internal footer -->
</div>
<div ng-if="!$root.isInternalPage" id="footer" class="hidden-print">
<!-- external footer -->
</div>
</div>
</body>
Alternatively, you could assign your variable on $rootScope inside one of your controllers:
app.controller('ctrl', function($rootScope) {
$rootScope.isInternalPage = true;
});
What you can do in this case is create an AngularJS service: "You can use services to organize and share code across your app"
angular.module('core').service('GlobalVars', [ 'addDependenciesHere',
function(addDependenciesHere) {
this.isInternalPage = someVal ? true : false
}
]);
Then inject this into the constructor for each controller
angular.module('core').controller('HomeController', ['$scope', 'GlobalVars',
function ($scope, GlobalVars) {
$scope.globals = GlobalVars;
}
]);
Then in your view you can access this directly
<body ng-class="{menu-right-hidden: globals.isInternalPage }">

Display Scope Variable in AngularJS Template

I'm running into a very odd situation trying to display a simple scope variable inside an angularjs template. Here's the simplified template code:
<div id="Parent" data-ng-controller="MyController">
{{ScopeVariable}} <!-- Diplays Just Fine -->
<div>
... Some Buttons ...
{{ScopeVariable}} <!-- Here it displays as {{ScopeVariable}}. Why? -->
</div>
<div ng-repeat="SomeElement in SomeScopeArray">
{{ScopeVariable}} <!-- Diplays Just Fine -->
</div>
</div>
The same single scope variable displays correctly inside the controller element as well as a repeated div. But if I try to display it inside a simple div, it fails.

[Angular JS]- Tabs Pane Example - Dynamic Add Tab

I have used the example from Angular JS Homepage and modified it to meet the requirements.
I have added the tabs info in a scope array and manipulate the data based in some conditions.
Issues:
I have attached an ng-bind on tabItem.title, so any change in the text box will update the title, but i want to limit the displaying of the title by 10 chars
When i create a new tab, i want that tab to be the selected one.
How can i select a tab based on some action taken (like on a click move from tab 1 to tab 2)
Fiddle: http://jsfiddle.net/austinnoronha/NWwcT
<br/><br/>
<div ng-cloak ng-app="TabsApp">
<div class="container" ng-controller="TabManagerCtrl">
<span class="label label-info label-ext" ng-click="tabManager.addTab()" style="cursor:pointer">Add a Tab</span><br/><br/>
<div>
<div tabs>
<div ng-repeat="tabInfo in tabManager.tabItems" pane title="{{ tabInfo.title }}">
<p>{{ tabInfo.content }}</p>
<input type="text" ng-model="tabInfo.title" ng-change="tabManager.getTitle(tabInfo)">
</div>
</div>
</div>
<br/><br/><br/>
</div><!-- /container -->
</div> <!-- /container -->
</div> <!-- /app -->
that's strange...
The limitTo filter doesn't seem to work, but you can create a new one and change your line
<div ng-repeat="tabInfo in tabManager.tabItems" pane title="{{ tabInfo.title }}">
by
<div ng-repeat="tabInfo in tabManager.tabItems" pane title="{{ tabInfo.title | limit:10}}">
with
angularApp.filter('limit', function() {
return function (input, value) {
return input.substr(0,value);
};
});
For the select one, I think it doesn't work because you have to have access to the pane scope. One way to do it is to access to access the property from the pane when you create it. In the pane directive, just add :
if(scope.$parent.tabInfo.selected) tabsCtrl.select(scope);
just after the tabsCtrl.addPane(scope); line. But then you also have to change the tabs directive so that the line
$scope.select = function(pane) {
become
this.select = $scope.select = function(pane) {
For your 3rd question, I don't know how to do it in that scheme.
I would make the pane directive different, putting the select function out of the directive, and binding it directly to your tabManager object.
Like this : http://jsfiddle.net/NWwcT/2/
In this cas, you have the 3 requirements, and you can select the tab from ouside by calling tabManager.select(index)

How can I hide the display of a page until the ng-include elements are available?

I am using the following code block:
<section id="content">
<div class="block-border">
<div data-ng-controller="AdminGridContentController">
<ng-include src="'/Content/app/admin/partials/grid-content-base.html'"></ng-include>
<ng-include src="'/Content/app/admin/partials/table-content.html'"></ng-include>
<ng-include src="'/Content/app/admin/partials/modal-content.html'"></ng-include>
</div>
</div>
</section>
This works but when it displays first of all it displays a "block-border" which in my case is a shadow border. Then after a short time the inside contents display.
Is there a way I can make it so the outer <DIV> does not show until the inside includes are ready?
Yo should try ngCloak:
The ngCloak directive is used to prevent the Angular html template from being briefly displayed by the browser in its raw (uncompiled) form while your application is loading. Use this directive to avoid the undesirable flicker effect caused by the html template display.
http://docs.angularjs.org/api/ng.directive:ngCloak
so... in your case:
<section id="content">
<div class="block-border">
<div data-ng-controller="AdminGridContentController" ng-cloak>
<ng-include src="'/Content/app/admin/partials/grid-content-base.html'"></ng-include>
<ng-include src="'/Content/app/admin/partials/table-content.html'"></ng-include>
<ng-include src="'/Content/app/admin/partials/modal-content.html'"></ng-include>
</div>
</div>
</section>
Use this:
HTML
<div data-ng-controller="AdminGridContentController">
<ng-include src="'/Content/app/admin/partials/grid-content-base.html'" ng-show="isLoaded"></ng-include>
<ng-include src="'/Content/app/admin/partials/table-content.html'" ng-show="isLoaded"></ng-include>
<ng-include src="'/Content/app/admin/partials/modal-content.html'" ng-show="isLoaded"></ng-include>
</div>
Javascript
yourApp.controller('AppController', ['$rootScope', function ($scope, $rootScope,) {
$scope.isLoaded = false;
$rootScope.$on('$includeContentLoaded', function(event) {
$scope.isLoaded = true;
});
}]);
References
ng-show
ng-include
The ng-include directive raises an $includeContentLoaded event. You could use that to set a value which in turn controls a ng-show directive placed on the block-border element.
https://github.com/angular/angular.js/blob/master/src/ng/directive/ngInclude.js#L178

Resources