Angular bind variable from controller to view inside html - angularjs

Need to bind variable from controller to view:
In Index html:
<body ng-app="widget" ng-controller="WidgetCtrl">
<div ng-view class="chatWidget"></div>
</body>
In controller:
$scope.showHideSchedule = true;
In view:
<div ng-show="WidgetCtrl.showHideSchedule">{{WidgetCtrl.showHideSchedule}}</div>
WidgetCtrl.showHideSchedule - doesn't works

Try to put an alias for controller like
<body ng-app="widget" ng-controller="WidgetCtrl as wg">
<div ng-view class="chatWidget"></div>
</body>
<div ng-show="wg.showHideSchedule">{{wg.showHideSchedule}}</div>

Using ng-view like you are. I would set up the html body like this
<body ng-app="widget" ng-controller="MainCtrl">
<div ng-view class="chatWidget"></div>
</body>
Then I would set the widget.html file like this
<div ng-show="widget.showHideSchedule">{{widget.widgetName}}</div>
Then your js code should look something like this in order to use that widget alias
.controller('WidgetCtrl',
function() {
this.showHideSchedule = true;
this.widgetName = 'new widget';
}])
Here is a plunker of this
https://plnkr.co/edit/l6lmAByRXm3dYfHIrARX?p=preview

It works by me with help of $scope.$broadcast event. I am not sure is it a best solution, but it works.

Related

How to change scope when controller is changed using Angular routes without using $rootScope

https://plnkr.co/edit/U9tL95qS5AgsPu6nNwVD/
I am able to change ng-view with templateUrl. But it is not updating {{msg}} when I am updating it using $scope.msg in every new controller.
Is there a way to update it without using $rootscope. Since I have heard that $rootScope practise is bad.
I guess I Am not registering the controller ??
I am new to Angular.
I dont know how to use services
in index.html
app.controller("redCtrl", ['$scope', '$route', function($scope, $route) {
$scope.msg = "I love red"; //NOT WORKING **************
}]);
check out this plnkr https://plnkr.co/edit/rvIZouNydPpwFgsIiVaf
#Rohitas Behera The reason is simple you are using
<div ng-app="myApp" ng-controller="mainController">
<p>Main</p>
Red
Green
Blue
<div ng-view>
</div>
{{msg}} <!-- why using here !>
</div>
so this time the msg is in scope of maincontroller . There are not other controller in scope
To do so remove {{msg}} from index.html and place it in there respective page.
Like this.
blue.html
<div style="background-color:#2196f3;">
<h1>Blue {{msg}}</h1>
</div>
same for all html page.
To alter the value {{msg}} in different context/controller, you will need to write {{msg}} in individual .html files where you have set the scope of respective controller.
As of now the variable is accessible only to your mainController as it is seen in index.html only, hence the value never changes.
You need to remove it from index.html and put it in every html.
here is the fixed plunkr
you have to add {{msg}} in every template.like this
<div style="background-color:#f44336;">
<h1>Red</h1>
{{msg}}
</div>
and remove {{msg}} form index.html page because maincontroller is working for index page and the modified page like this
<div ng-app="myApp" ng-controller="mainController">
<p>Main</p>
Red
Green
Blue
<div ng-view>

angularJS: How to conditionnaly display an element outside of ng-view?

Considering the following angular 1.X index.html file:
<div ng-app="app" class="hero-unit">
<a ng-show="!isHomePage" href="#!/home">Home</a>
<div class="container-fluid">
<div ng-view></div>
</div>
</div>
I would like to display the element <a ng-show="!isHomePage" href="#!/home">Home</a> only when the location is not the home page?
How should I proceed? Should I map this element on a dedicated controller as mainController? Is that a good practice?
Ways to achieve this :
You can create a parent level controller(outside ng-view) in the application and then check the current route and based on that implement the condition.
Home
To get the current path you can use :
app.run(function ($rootScope) {
$rootScope.$on('$routeChangeSuccess', function (e, current, pre) {
console.log(current.originalPath); // Do not use $$route here it is private
});
});
OR
$location.path()
You can use $scope.$emit if you want to do it based on any event in the view.$emit will help in communication between child to parent.
You can create an angular service through that you can pass the current state of the application and based on that implement the condition.
Try moving ng-app to the body level, and then use a service in the $rootScope to detect if it's the home page or not - I do this in some of my apps.
e.g.
<body ng-app="app">
<div class="hero-unit">
<a ng-show="!NavigationService.isHomePage()" href="#!/home">Home</a>
<input id="token" type="hidden" value="{{token}}">
<div class="container-fluid">
<div ng-view></div>
</div>
Then in your app.js run method, set the NavigationService to the rootScope,
e.g.
$rootScope.NavigationService = NavigationService;
You can check current url:
See this example from:
https://docs.angularjs.org/api/ngRoute/directive/ngView
<div ng-controller="MainCtrl as main">
<div class="view-animate-container">
<div ng-view class="view-animate"></div>
</div>
<hr />
$location.path() = {{main.$location.path()}}
$route.current.templateUrl = {{main.$route.current.templateUrl}}
$route.current.params = {{main.$route.current.params}}
$routeParams = {{main.$routeParams}}
</div>

Include template on ng-click in angulajs

I have created discussion forum application in angularjs. Once the user clicked the reply button on the post, I want to show the editor which is in the separate html file. How can I include that template on clicking the ng-click under that specific post.
How about a combination of ng-include with ng-if?
If you want to inject a template based on a certain condition, you can do it like this:
<div ng-include="'template.html'" ng-if="yourCondition"> </div>
where template.html is your filename and yourCondition should be an boolean expression.
Here is a plnkr to demonstrate: http://plnkr.co/edit/m50nKigoOWYwuczBIQdQ?p=preview
As suggested above we can use combination of ng-if and ng-include to achieve require functionality :
<html ng-app="includeApp">
<head>
<script type ="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<script src="AppController.js"></script>
</head>
<body ng-controller="AppCtrl">
<button ng-click="injectReply()">Include Reply</button>
<div ng-include="'reply.html'" ng-if="isReplyIncluded"></div>
</body>
</html>
Now code containing AppController.js :
angular.module('includeApp',[])
.controller('AppCtrl',['$scope',function($scope){
$scope.isReplyIncluded=false;
$scope.injectReply= function (){
//add reply.html by making this variable true
$scope.isReplyIncluded=true;
}
}]);
Reply.html
<div>
You can add your editor html content here
</div>

AngularJS - How to make SPA with multiple sections

I have the following basic breakdown of my layout:
<body>
<div id="left"></div>
<div id="content" ng-view></div>
<div id="right"></div>
<body>
I use ng-view in the main content to load the content dynamically through $routeProvider and templateUrl. However, the content in #left and #right also sometime need to change depending on what page I go to.
What's the best way to add/remove elements to #left and #right dynamically? I would basically want that if I load /view1 with controller View1Controller, then if this view has extra components, then I can display them within View1Controller.
In order to do this sort of requirement (without any extra plugins) you'll have to pull your left and right views out into their own view and set each route's main view to include left, content, and right themselves.
Example:
<!-- Core Html-->
<body ng-app>
<div ng-controller="MainCtrl" ng-view></div>
</body>
MainCtrl.js
angular.module('MyApp').controller('MainCtrl', function($scope){
$scope.defaults = {
leftView: "views/view1.html",
rightView: "views/view2.html"
}
});
Route /view1 and it's main view (call it view1.html)
<div ng-controller="View1Ctrl">
<div id="left" ng-include="defaults.leftView"></div>
<div id="content" ng-include="contentView"></div>
<div id="right" ng-include="defaults.rightView></div>
</div>
View1Ctrl
angular.module('MyApp').controller('View1Ctrl', function($scope){
$scope.contentView = "views/view1/firstPanel.html";
//Add some other functions to change $scope.contentView to say
//"views/view1/secondPanel.html"
//You could also temporarily replace $scope.defaults.leftView
//and rightView to show the View1 route in full screen so to speak. like so
$scope.setFullPanel = function(){
$scope.defaults.leftView = ''; //or something else
$scope.defaults.rightView = '';
$scope.contentView = "views/view1/fullScreenPanel.html";
}
});
Route /view2 and it's main view (call it view2.html)
<div ng-controller="View2Ctrl">
<div id="left" ng-include="defaults.leftView"></div>
<div id="content" ng-include="contentView"></div>
<div id="right" ng-include="defaults.rightView></div>
</div>
View2Ctrl
angular.module('MyApp').controller('View2Ctrl', function($scope){
$scope.contentView = "views/view2/firstPanel.html";
//Add some other functions to change $scope.contentView to say
//"views/view2/secondPanel.html"
});
Now that you have the routes and views setup for default left and right panels you could setup a route for a panel with no left and right for example:
<div ng-controller="View3Ctrl">
<div id="content" ng-include="contentView"></div>
</div>
View3Ctrl
angular.module('MyApp').controller('View3Ctrl', function($scope){
$scope.contentView = "views/view3/wholeScreenPanel.html";
});
Hope this helps. Also it's important for "scope hierarchy reasons" to ensure the higher level "default" variables are saved on $scope.defaults so any changes in View1Ctrl or View2Ctrl to $scope.defaults will be properly update throughout all your controllers / views.
I do not completely understand your requirement but did you take a look of the ui-router from angular-ui. Link: http://angular-ui.github.io/ui-router/.
Btw, you can see sample app here: http://angular-ui.github.io/ui-router/sample/#/ Hope it helps.

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