Wondering how to use 2 the same controllers in a single view in Angular, I separated my controllers in different files to make a clean ctrl structure, but wondering if you're allowed to do something like this?
Basically I want to update the table view after uploading a file, its somewhat working but I have to refresh the whole page for the view to refresh.
<div class="view">
<div ng-controller="myCtrl as vm">
controller the table
</div>
<div ng-controller="otherCtrl as vm"> </div>
<div ng-controller="myCtrl as vm">
<button ng-click="clickbtn()"></button>
</div>
</div>
This code is in myCtrl controller.
$scope.$on("$UploadFile", function (event) {
// do the action here digestion
});
$scope.uploadCv = function(event) {
$scope.$broadcast("$UploadFile");
}
Related
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>
I'm using ui-router and I have the following index view:
<div ng-include="'/views/topbar.html'"></div>
<div class="vm-view">
<div class="container-fluid" ui-view></div>
</div>
So, all the content will be loaded under the top bar. Thats ok, but I need to render a single view without the top bar (full screen). I want to do this without use named views. I want to preserve the index structure intact and states hierarchy too.
Try to add some class depending on current state to hide topbar
<div ng-controller="someCtrl">
<div ng-class="{hide:isSpecialState()}" ng-include="'/views/topbar.html'"></div>
<div class="vm-view">
<div class="container-fluid" ui-view></div>
</div>
</div>
app.controller('someCtrl', function($state) {
$scope.isSpecialState = function() {
return $state.is('<STATE_NAME>');
};
})
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.
Question:
How can I add a "Login" view/route to my angular app that hides an element that is outside the ng-view DOM?
Situation:
In my Angular page, I have a navigation tree view on the left and the main view in the center:
<div ng-app="myApp">
<div class="col-sm-3" ng-controller="TreeController">
<div treeviewdirective-here>
</div>
</div>
<div class="col-sm-9 content" ng-view="">
</div>
</div>
Each node in the treeview changes the location using something like window.location.hash = '#/' + routeForTheClickedItem;.
Using the standard routing, this works great, i.e. the tree is not reloaded each time, but only the main "window".
Problem:
I want to add a login functionality with a login view. For this view, the treeview should not be visible - only after the login. To achieve this with the normal routing, I know I could move the ng-view one level up, i.e. embed the treeview into each view - but this would result in the treeview being reloaded with every route change.
Is there an easy alternative that allows me to check what page is displayed in the ng-view? Or check some other variable set during the routing? Then I could use something like:
<div class="col-sm-3" ng-controller="TreeController" ng-show="IsUserLoggedIn">
You could listen for a routeChangeSuccess outside ng-view
$scope.$on('$routeChangeSuccess', function (event, currentRoute, previousRoute) {
//do something here
});
hope that helps, you can catch me on angularjs IRC - maurycyg
You could define a controller at the top div level.
Something like:
<div ng-app="myApp" ng-controller="MainController">
and in MainController inject a Session. Something like Session is enough to decide whether to show the tree.
Here's an example of MainController:
_app.controller('MainController', function ($scope, SessionService) {
$scope.user = SessionService.getUser();
});
Here's an example of SessionService:
_app.factory('SessionService', function() {
var user = null;
return {
getUser : function() {
return user;
},
setUser : function(newUser) {
user= newUser;
}
};
});
Of course, when you login you must set the user to the SessionService. Therefore, a SessionService has to be injected into your LoginController, too.
And finally, your html:
<div ng-app="myApp" ng-controller="MainController">
<div class="col-sm-3" ng-controller="TreeController">
<div ng-hide="user == null" treeviewdirective-here>
</div>
</div>
<div class="col-sm-9 content" ng-view="">
</div>
</div>
I am using multiple named ui-views in a single controller. Everything is working as spected when name the ui-view in the html file with this code:
<div class="box">
<div ui-view="selector"></div>
<div ui-view="widget1"></div>
<div ui-view="widget2"></div>
<div ui-view="widget3"></div>
<div ui-view="widget4"></div>
</div>
But when I want to load dynamically some of those views with a ng-repeat it does not update the information.
<div class="widgets">
<div class="widget-container" ng-repeat="widget in widgets">
<div ui-view="{{widget}}"></div>
</div>
</div>
How could I load ui-views from my ng-repeat?
This hadn't been answered so i decided to go ahead and show how to do it. Unfortunately for some reason the attempt in the question didn't work but what you can do is link to a function between curly brackets and return the string of the view you want. For instance the controller would look like this:
$scope.groups = ['main','cases', 'models'];
$scope.pickView = function(index){
return $scope.groups[index];
};