I want to use Angular-route to change the controller used in a page
This is some part of my angular code
var cat_list = angular.module('getCat', ['ngRoute']);
cat_list.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('category/upcoming', {
controller: 'getUpcoming'
})
.when('category/popular', {
controller: 'getPopular'
});
$locationProvider.html5Mode(true);
});
cat_list.controller('getUpcoming', ['$scope', function($scope, $routeParams) {
//controller code goes here
});
cat_list.controller('getPopular', ['$scope', function($scope, $routeParams) {
//controller code goes here
});
and this is some part of my html
<div class="row" ng-app="getCat">
<div class="col-md-12">
<!-- something happen in here -->
</div>
</div>
but when I tried to visit http://localhost/project/category/upcoming or http://localhost/project/category/popularthe route is not working (no controller picked or selected)
did I miss something?
Try this
var cat_list = angular.module('getCat', ['ngRoute']);
cat_list.config(['$routeProvider', '$locationProvider',
etc etc.
Could you also please explain why you want to use different controllers on the same page? Why dont you use two different partials to create two seperate pages for upcoming and popular?
Or, a different approach would be to just use the same controller, and filter your results using the appropriate directive, without changing the stuff that you load each time.
Have to mention ng-view, so that this directive is the placeholder to replace your view partials on url changes.
<div class="row" ng-app="getCat">
<div class="col-md-12">
<div ng-view></div> // ---- This is the thing you missed
</div>
</div>
Related
I am learning how to use ngRoute to split my html forms into separate views. When I add data to the main array in the index.html the array updates correctly, but when I try the same approach in the html forms that are added in through the ng-view, the array does not render correctly. I can debug and see that the array is getting the new name added, but it will not render on the html.
Index.html
<h1> Names </h1>
<ul ng-repeat="name in names">
<li>{{name.fname}}</li>
</ul>
<h1>Add name in index.html</h1>
<input type="text" ng-model="name" />
<button ng-click="addName(name)">add name</button>
<ul>
<li> First</li>
<li> Second</li>
</ul>
<div class="container">
<div ng-view></div>
</div>
Apps.js
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function ($routeProvider) {
$routeProvider
.when('/first', {
templateUrl: 'pages/first.html',
controller: 'mainController'
})
.when('/second', {
templateUrl: 'pages/second.html',
controller: 'mainController'
})
});
myApp.controller('mainController', ['$scope', '$log', function($scope, $log) {
$scope.names = [{fname:'john',lname:'doe'},{fname:'jane',lname:'doe'}];
$scope.addName = function(name){
$scope.names.push({fname:name,lname:'no last name'});
}
}]);
first and second.html are identical
<h1>Add name in first.html</h1>
<input type="text" ng-model="name" />
<button ng-click="addName(name)">add name</button>
This is by design.
The $scope is limited to the scope of the controller, which is everything that is rendered inside the ng-view. This means there are two collections named names, one on the app scope, and one on the controller scope. When you modify the names collection inside the controller, it only modifies this collection, not the one referenced in the root level of the app. (I am assuming that you bind mainController to the body tag, otherwise the addName() in index.html wouldn't work. This by itself is not a great choice, you should not put another controller instance into itself, unless you absolutely know what you are doing.)
The proper way to handle this situation is to put the names collection and the addName() function into a service that you inject into your controllers.
I have a JavaScript web app where I used AngularJS to ease things up, but now I bumped into a little problem.
I want to change viewfrom an ng-controller. I use $location.path to do this, but sadly, nothing happens. If I check the $location object, the path will be changed correctly, but the view isn't changing.
I have an ng-view in my Home.html. This is the config I wrote for it:
<html ng-app="app">
...
<body>
<div id="navigation-menu" ng-controller="NavigatorController">
<a class="menulink" ng-class="{ active: isActive('/labels')}" href="#page2">Page2</a>
<a class="menulink" ng-class="{ active: isActive('/labels')}" href="#page3">Page3</a>
</div>
<div ng-view></div>
</body>
</html>
This is the config I made for the $routeProvider which works flawlessly when used in the menusystem
myApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'Page1.html',
controller: 'Page1Controller'
})
.when('/page2', {
templateUrl: 'Page2.html',
controller: 'Page2Controller'
})
.when('/page3', {
templateUrl: 'Page3.html',
controller: 'Page3Controller'
});
});
Upon opening the app I want to show the Page1.html in the ng-view, so that's sorted with the '/' url thing, I guess.
The problem is, that from every other controller, I want to be able to get back to the Page1.html.
I tried making an event in every other controller, like this:
$scope.NavigateBack = function() {
$location.path('/');
}
It's not working, sadly. I don't get any error messages though... I tried it with different addresses in the path, like "/page2", but nothing worked.
What am I doing wrong, that the view isn't changing and the page isn't navigating?
I recommend use
$window.location = "#/"
but don't forgot to inject $window to your controller
Define behaviour in the Page2Controller, for example:
$scope.goBack = function(){
$location.path("#/");
}
And add some button inside of Page2.html:
<button ng-click="goBack()">Return</button>
You might also need to change your navigation links href attribute to #/page2 and #/page3
<div
class="row caption-view"
ng-include="'app/views/inventory/grid-view/part.html'"
module="subscriber"
alias="il"
ng-controller="GridController as il"
ng-init="il.setGridParams(cse.gridParams.findCation);
cse.findCaptionGrid = il">
</div>
I have controller ('cse') and in its view i have ng-include with its controller. When everything loaded i can use 'cse.findCaptionGrid' to manipulate with 'GridController' controller.
Problem:
'cse' controller loads and i need to start manipulate with 'GridController' (aka. 'cse.findCaptionGrid') controller. But i cant use 'cse.findCaptionGrid' till ng-include has executed. I tried to use $timeout, but it didnt help. I set timeout to 5000 then it worked.
Question: Is it possible to define 'ng-init="il.setGridParams(cse.gridParams.findCation); cse.findCaptionGrid = il"' part in controller so i can start use it? And in html i just show where this should be shown?
create a directive :
<div my-directive
class="row caption-view"
module="subscriber"
alias="il"/>
angular.module("yourApp").directive('myDirective', [function(){
return {
controller: "GridController as il",
templateUrl: "app/views/inventory/grid-view/part.html"
};
}]);
and inside your controller :
this.setGridParams(cse.gridParams.findCation);
cse.findCaptionGrid = this;
I have a url that's getting passed into my Angular code via Rails. However, when I try to pick up a parameter in the url, it shows up as blank. Can anyone help me out?
Sample url: http://localhost:3000/events/event1
Plnkr: http://plnkr.co/edit/yG8wAZHhgPtH2PBFzql3?p=preview
Angular:
eventsApp = angular.module('EventsApp', ['ngRoute'])
eventsApp.config [
'$routeProvider'
'$locationProvider'
($routeProvider, $locationProvider) ->
$locationProvider.html5Mode(true)
$routeProvider.when '/events/:eventName',
templateUrl: '../../views/events/events.html.erb'
controller: 'EventsCtrl'
return
]
eventsApp.controller('EventsCtrl', [
'$scope'
'$routeParams'
($scope, $routeParams) ->
console.log($routeParams.eventName) # shows up as undefined
$scope.greeting = $routeParams.eventName
])
HTML:
events.html.erb
<div>
{{greeting}}
</div>
application.html.erb (overall layout)
<div id="content" ng-app="EventsApp">
<div ng-view></div>
<%= yield %>
</div>
Edit: As suggested, I've moved ng-app and ng-view into the layout and kept only the div inside events.html.erb
If the bugs pointed by Karaxuna still giving you empty result, it might be because of the asynchronous operation of $routeParams
$routeParams usually takes some time to load. It is being loaded asynchronously. When you are trying to use it, it might not ready and still empty. One approach is, create event listener when the route is ready.
$scope.$on('$routeChangeSuccess', function() {
console.log($routeParams.eventName);
});
It's because you have included controller with ng-controller directive instead of ng-view. It must be like this:
<body ng-app="EventsApp">
<div ng-view></div>
</body>
In events.html.erb:
<div>
{{greeting}}
</div>
I am beginner in angular js
HTML
<div ng-app="myapp">
<div ng-controller="maincontrol">
<div ng-show="!vis">show</div>
<div ng-show="vis">hide</div>
</div>
<div ng-view></div>
</div>
JS
var app = angular.module('myapp', ['ngRoute'])
app.controller('maincontrol', function ($scope) {
$scope.vis = true;
$scope.fun = function () {
if ($scope.user == "home" && $scope.pass == "home") {
console.log($scope.user, $scope.pass);
$scope.vis = false;
}
}
})
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'home.html'
})
.when('/contact', {
templateUrl: 'contact.html'
})
});
and also i have two html pages like
home.html
<div ng-controller="maincontrol">
<input ng-model="user"/>
<input ng-model="pass"/>
<div ng-click="fun()">
click
</div>
</div>
contact.html
<div>
contact
</div>
my expectation is after entering home into user and pass. if i click 'click' i need to show 'show' label instead of 'hide'. pls help me.
Each controller has its own scope, when you wrote $scope.vis=false on fun(), you actually created a new variable on maincontroler1 scope. If you expected this variable to affect the view which is binded to maincontroler scope, it won't happen.
I suggest 2 options:
You can use one controller for entire app (If you use same controller in two tags it will still create a new scope although it is the same controller), this way the fun() method that was called from the first view will change the boolean in the single controller and will affect the second view. Please note when you use ng-view you will have to get the variable from the parent.
So I used this code:
$parent.user
$parent.pass
Create this working plunker for you.
Share the vis boolean between 2 controllers using a service. You can
use this post for this option.
You can also use reach parent controller scope from child controller, that can be done if ng-view will be nested in the outer controller. You can use this post for option 3.