Want to associate a controller to main page in Angular - angularjs

I am currently creating an app that has a nav bar. I want a particular function to be invoked every time the submit button in the nav bar is pressed regardless of route/view. I am having trouble because here in my routes file I have created associations that changed based on route. The form is found in <form class="pure-form" ng-submit="somefunc()">
routes.js
angular.module('LiveAPP', ['ngRoute',
'LiveAPP.main',
'LiveAPP.signUp',
'LiveAPP.artist'])
.config(function($routeProvider, $httpProvider) {
$routeProvider
.when('/', {
templateUrl : '/home.html',
controller : 'mainCtrl'
})
.when('/signup',{
templateUrl : '/signup.html',
controller : 'signUpCtrl'
})
.when('/artist',{
templateUrl : '/artistpage.html',
controller : 'artistCtrl'
})
})
index.html
<body ng-app='LiveAPP'>
<div class="header">
<form class="pure-form" ng-submit="somefunc(field)">
<input ng-model="field" type="text" placeholder="Artist" name="field">
<button type="submit">Search</button>
</form>
Sign Up
artistPage
</div>
<div ng-view></div>
</body>
mainCtrl
angular.module('LiveAPP.main',[])
.controller('mainCtrl', ['$scope','$http', '$location',mainCtrl]);
function mainCtrl($scope,$http,$location){
$scope.somefunc = function(searchvalue){
console.log(searchvalue)
}
};
Right now the submit button is associated with the mainCtrl which is related to the home.html. Any ideas?

In general you have a couple approaches:
If you need some logic to be available in more than one controller you can create a service and inject it to your controllers.
You can implement controller inheritance.
There are a couple ways to implement controller inheritance.
This is one example of how to do that:
var app = angular.module('myApp', []);
app.controller('MainCtrl', function() {
this.methodclick=function(){
alert('I am Parents')
}
});
app.controller('ChildCtrl', function($controller) {
var ChildCtrl=this;
ChildCtrl.child = $controller('MainCtrl',{});
});
But in my opinion it is better to implement a service.

Related

$rootScope changed doesn't reflect on template

I'm a newbie in angularjs. I'm trying to build a simple app which contain login page and dashbboard page.
Now, I got a problem with updating html template when rootScope changed.
Here is my component template :
<!-- show dashboard page app >
<div layout="column">
<div ng-show="$rootScope.isAuthenticated">
<pm-header></pm-header>
<div layout="row">
<pm-sidebar></pm-sidebar>
<div layout="column" class="sitecontent" layout-padding>
<md-content ui-view></md-content>
</div>
</div>
</div>
<!-- show login page app >
<div ng-hide="$rootScope.isAuthenticated">
<pm-homeheader></pm-homeheader>
<div layout="row">
<md-content ui-view flex></md-content>
</div>
</div>
</div>
Login blockcodes :
'use strict'
export default ['$rootScope', '$state', '$http', '$window', function($rootScope, $state, $http, $window) {
this.user = {};
this.login = () => {
$http.post('./api/auth/login', this.user)
.success(function(data, status, headers, config) {
$window.sessionStorage.token = data.token;
$rootScope.user = data.user;
$rootScope.isAuthenticated = true;
$state.go('home');
})
.error(function(data, status, headers, config) {
delete $window.sessionStorage.token;
})
};
}]
My problem is when I logged and go back to home state, the ui-router updated the template to ui-view, but the ng-show="$rootScope.isAuthenticated" didn't reflect the changes on html, it show the block codes of home page instead of dashboard page.
Can anyone help me for this case, many thanks.
Use:
ng-show="$root.isAuthenticated"
You can't access $rootScope in the template, when you access it in a controller you inject it in. $root works because when angular creates a rootScope it sets a reference to $root to itself so its just like accessing any other property on the scope.
Refer to AngularJS rootScope code Line 135: https://github.com/angular/angular.js/blob/v1.3.6/src/ng/rootScope.js#L135
You should not use either $scope OR $rootScope while using variable for binding on HTML, so as soon as variable update in $rootScope, isAuthenticated will be taken from $rootScope while evaluating value of ng-show.
ng-show="isAuthenticated"
Though directly using $rootScope, wouldn't consider as a good practice. I'd suggest you to create a service/factory with a name userService that will have shareable user information among-st angular components.

Angular: Why Won't Model Update Outside Of View In Same Controller?

I have found a number of posts talking about models/views not updating, but I still can't figure this out. I'm new to Angular, btw so I suspect this is noob issue.
I have the below Angular app.
When the text input test_var is edited, the edited value isn't updated in the sidebar, but it is in the view. Why and how do I fix it?
This works when I don't use views and routes.
I've tried a sidebar controller, but no difference. I've tried $rootScope, which partially worked (it broke other functionality), but I'd prefer not to use a global scope.
Thanks for taking a look.
HTML
<body>
<div ng-app="rxApp" ng-controller="WizardCtrl">
<div class="ng-view">
</div>
<div class="sidebar">
<span ng-bind="test_var"></span>
</div>
</div>
</body>
View (One.html)
<input ng-model="test_var" />
<span ng-bind="test_var"></span>
Controller
rxApp.controller( 'WizardCtrl', function ( $scope, $http, $routeParams, $location, FileUploader ) {
$scope.test_var = 'please work!';
)};
Routes
rxApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/one', {
templateUrl: 'templates/one.html',
controller: 'WizardCtrl'
}).
when('/two', {
templateUrl: 'templates/two.html',
controller: 'WizardCtrl'
}).
otherwise({
redirectTo: '/one'
});
}
]);
Controllers are disposed when transmuting routes.
As for Best Practice you should create a Service to handle that data. You should not use controllers to carry data between views. In your case, the problem is Controllers are disposed when transmuting routes.
See the angular docs on how to use controllers correctly. http://docs.angularjs.org/guide/dev_guide.mvc.understanding_controller
The problem is the making of model variables.
You have to have a dot in model. Make your model point to an object.
So in your controller do like this -
rxApp.controller('WizardCtrl',function($scope, $http, $routeParams,$location, FileUploader){
$scope.test ={
var : 'please work!'
};
)};
View (One.html)
<input ng-model="test.var" />
<span ng-bind="test.var"></span>
HTML
<body>
<div ng-app="rxApp" ng-controller="WizardCtrl">
<div class="ng-view">
</div>
<div class="sidebar">
<span ng-bind="test.var"></span>
</div>
</div>
</body>
To read more about scope go through this UnderStanding Scopes

Loading a Route within a Route in Angular

I have some HTML which looks like this:
<body ng-controller="main">
<div id="main">
<div ng-view></div>
</div>
</body>
Here is the controller:
var app = angular.module('buildson', ['ngRoute', 'ngAnimate']);
app.controller('main', function($scope) {
$scope.$on("$routeChangeSuccess", function (event, currentRoute, previousRoute) {
window.scrollTo(0, 0);
});
});
And here is the Routing:
//ROUTING
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl : 'home.html'
})
.when('/courses', {
templateUrl : 'views/coursesTeaching.html'
});
});
Here is coursesTeaching.html
<div class="coursesList">
[Display a list of courses here]
Display Documentation
</div>
And here is documentationWidget.html
Documentation Content is in this file
What I want to do is when they click on this link Display Documentation It loads the documentationWidget.html content into the <div class="documentationWidget"></div> spot, I suppose it is a view within a view or a sub-route. I can't do it with jQuery Ajax or anything because I want to be able to use Angular variables inside of the loaded html file.
Take a look at ui-router as an alternative to ngRoute. This has good support for nested views amongst other things: https://github.com/angular-ui/ui-router
This has also been discussed in more detail here: Difference between ng-route & ui-router
I've been told you should use the third-party library ui-router for complex routing operations.

Angular ng-model is not working in multiples views

I'm trying to build a single page application with ng-view but at this time I've a problem about ng-model. I've followed this tutorial here and all is working perfectly except ng-model.
I've added a form with a single input text with ng-model and a button who calls a function in my controller. When button is submitted, I load a view where I try to get my ng-model but whithout success...
See below my code :
home.html
<div>
<h2>Home Page</h2>
<form>
<input type="text" ng-model="actia.name" placeholder="Saisir un mot"><br>
<button ng-click="toSend()">OK</button>
</form>
</div>
app.js
var MyApp = angular.module('MyApp', ['ngRoute']);
MyApp.config(function($routeProvider, $locationProvider){
$routeProvider
.when('/',{
templateUrl : 'pages/home.html',
controller : 'MainController'
}).when('/contact',{
templateUrl : 'pages/contact.html',
controller : 'MainController'
});
// $locationProvider.html5Mode(true);
});
MyApp.controller('MainController', function($scope, $location){
$scope.message = "Message du main Control";
$scope.actia = {
name : '',
lastname : 'goerge'
};
$scope.toSend = function(){
var donnees = $scope.actia;
// $location.url('/contact');
console.log(donnees);
};
});
contact.home
<div>
<h2>Contact Page</h2>
<p>Value is : {{actia.name}} {{actia.lastname}}</p>
</div>
{{actia.lastname}} is displayed but not {{actia.name}}
Have you any suggestions to solve this ?
Thanks in advance
That is because you get a new Controller for each route. They don't know each other.
YOu may need a factory/service to keep the data in sync between those two views.

how do I change background image of application based on url or routing?

I would like to change the background image of the application(Html Body) based on the url. And this I want to do in angularJS only :)
For eg:
1) if user visits the url like this,
www.domain.com/view1
Bellow image is shown
2) If user visits url
www.domain.com/view2
I want show other image
app.js
var app = angular.module('app', []);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
$routeProvider.otherwise({redirectTo: '/view1'});
}])
app.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode(true);
}]);;
Controler.js
app.controller('MyCtrl1',function($scope){
$scope.viewBackground="body"
console.log($scope.viewBackground);
})
app.controller('MyCtrl2',function($scope){
$scope.viewBackground="profile"
})
in the partial html, I am just doing like this
<div class="span12">
<p>
{{$scope.viewBackground}}zxz
</p>
</div>
But some reason I am not able to get the value of viewBackground property value.
I'm not sure I understand you correctly, but I hope so.
You have 2 options.
First - use different controllers for each page view1 and view2.
And use ng-class directive on the pages:
HTML:
<!-- "page" View 1 -->
<div ng-controller="View1Ctrl">
<div ng-class="viewBackground"> View 1 </div>
</div>
<!-- "page" View 2 -->
<div ng-controller="View2Ctrl">
<div ng-class="viewBackground"> View 2 </div>
</div>
JS:
var app = angular.module('app', []);
function View1Ctrl($scope) {
$scope.viewBackground = "background-small"
}
function View2Ctrl($scope) {
$scope.viewBackground = "background-big"
}
On your CSS:
.background-small{
height:200px;
width:200px;
background: url('...img1...');
}
.background-big{
height:400px;
width:400px;
background: url('...img2...');
}
Second option - use .run block, where you will add some logic to change the bg-image, but this is a poor option
If your controller you can check the $routeParams param and then set a scope variable to control the background image.
function announcements_detail_controller($scope, $rootScope, $routeParams, $http, $location)
{ //console.log($routeParams);
$scope.css_class_for_background_image = 'xxxx';//
}

Resources