AngularJS: Show view without replacing existing view when a route is changed - angularjs

I have a view in which I am listing out existing contacts.
route : /contacts
controller : contacts.list
view : /templates/list.html
I have another view in which I want to add a new contact
route : /contacts/add
controller : contacts.add
view : /templates/add.html
Using route, I am able to show either of these when needed.
But the challenge I am facing is to show the add form page in a popup when clicked on Add button instead of replacing list view.
Basically I want to link "Add" with the /contacts/add URL which will load the view in a popup and bind the controller to it, instead of replacing the entire view.
Please help me in how to think in Angular to achieve this.
Following is what I have currently.
var myModule =
angular
.module('myModule', [])
.config(['$routeProvider', function config($routeProvider){
$routeProvider
.when('/contacts', {
controller : 'contacts.list',
templateUrl : 'templates/contacts/list.html'
})
.when('/cotnacts/add', {
controller : 'contacts.add',
templateUrl : 'templates/contacts/add.html'
});
}]);

You might want to map angular routes to custom events and not really using <ng-view>
See this: www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm

Related

Automatically instantiate AngularJS controller nested in templateUrl

I'm just learning Angular and have a very basic app set up. When rendering some data via the templateUrl property of a route, what would be the best way to include a sub-controller in the returned template? For example, including a "createOrEditItem" template at the bottom of a "viewItem" template so that the "createOrEditItem" can be reused on its own later?
I've tried putting a div in the template with its ng-controller attribute set to a controller name that I've defined at the app level, but it's not being activated. Should this be done with a directive instead to make it instantiate when the master controller has its contents set, or am I missing something more fundamental?
yes, as mentioned in the later part of the question, you should be using a directive. Or, if using AngularJS >= v1.5, component should be the choice because they are pluggable and works well with nesting too.
Note that for the route also, you can directly use a component like this:
var myMod = angular.module('myMod', ['ngRoute']);
myMod.component('home', {
template: '<h1>Home</h1><p>Hello, {{ $ctrl.user.name }} !</p>',
// ^^^^ other components can be used here
controller: function() {
this.user = {name: 'world'};
}
});
myMod.config(function($routeProvider) {
$routeProvider.when('/', {
template: '<home></home>'
});
});
Now, as the comment suggests, you can freely use other components in the template of home component.
Hope this helps a bit!
A directive can be used.
Another option is to use a seperate view/route. So when you add a ui-view tag, you could define your view and route.
This is explained here:
https://scotch.io/tutorials/angular-routing-using-ui-router

Why is my $scope not updating in my View in Angular when using $location with angular-route?

Does anyone know why my $scope.userData isn't rendering in my View when using angular-route and Angular's $location service together?
My Situation:
In the code example below, I have an index page which iterates through users, allUsers, using angular's ng-repeat, as follows: ng-repeat="user in allUsers [note, for simplicity, I have left out the function in my controller snippet below that delivers allUsers, but is working correctly].
For each user, there is an edit button, which should run the $scope.findOne function, passing in the user itself as a parameter.
In my $scope.findOne function, a new partial is loaded using the $location service, and $scope.userData is updated to reflect this user. I want to access $scope.userData now on the new partial (my problem).
Problem:
The new partial loads, the user object seems to pass along fine, however $scope.userData becomes inaccessible on the front-end.
PseudoCode (What I'd Like):
// Iterate through allUsers (`user in allUsers`)
// When Edit button is clicked for `user`:
// Fire off `findOne` function passing in `user`
// Set `$scope.userData` to `user`
// Load `html/edit.html` partial
// Show `$scope.userData` on the page (should be `user` info):
PseudoCode (What's Happening Instead):
// Iterates through allUsers (`user in allUsers`)
// When Edit button is clicked:
// Fires off `findOne` function and passes `user`
// Sets $scope.userData` (console logging it after shows changes)
// Loads `html/edit.html`
// **DOES NOT show `$scope.userData` and appears empty.**
Angular Module Setup:
Both the /index.html page and the /edit.html page appear to be setup correctly with the appropriate controller assignments:
// Define Module:
var app = angular.module('app', ['ngRoute']);
// Define Routes:
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'html/index.html', // root route partial
controller: 'userController',
})
.when('/edit/:id', {
templateUrl: 'html/edit.html', // edit page partial
controller: 'userController',
})
.otherwise({
redirectTo: '/',
})
});
Angular Controller:
My angular controller (allUsers function now shown) shows the findOne function I'm trying to access, along with the use of the $location service:
app.controller('userController', ['$scope', 'userFactory', '$location', function($scope, userFactory, $location) {
$scope.findOne = function(myUser) {
$scope.userData = myUser;
console.log($scope.userData); // shows changes...(?)
$location.url('/edit/' + myUser._id); // redirects and partial loads OK...
};
}]);
In the following Index HTML example, clicking the Edit button triggers the $scope.findOne function fine, redirects the page and updates $scope.userData (console logs OK), but on the partial itself, $scope.userData does not seem to reflect the changes (what gives?):
Index Page HTML:
<div ng-repeat="user in allUsers">
<h1>{{user.username}}</h1>
<button ng-click="findOne(user)">Edit</button> <!-- runs findOne -->
</div>
Edit Partial HTML:
<h2>Edit:</h2>
{{userData}} <!-- $scope.userData displays nothing? -->
Summary:
Why does {{userData}} in my Edit Partial HTML not show anything?
I found a solution to my needs by creating a new controller, and having this other controller take over when the /edit.html page is loaded. The controller queries the DB on page load for the user based on req.params.id. This worked and I was able to carry on, but I have two separate controllers, when instead, I'd like to manage all CRUD operations from a single controller for my Users...(is this bad practice?)
I had initially tried the solution above, but got stuck with the $scope issue as outlined here in this write up. Any ideas what I'm doing wrong in getting my above data to render in my View? Your time and patience reading is genuinely valued! Thank you Stack Community!
My guess (mostly b/c I use angular-ui-router) is that when you navigate to the edit partial, a new controller is being instantiated, so the data on the $scope is lost.
Here are two common approaches I've seen:
Do what you described above to query the server for the user data using route params. Consider enabling the caching option for $http so it doesn't have to hit the server each time... but then you need to invalidate the cache when the data changes
Create a service that queries the server for the list of users. This service makes the user list available to the controller, and returns an individual user for editing.

Page navigation using routing

I am trying to navigate to a new jsp page on click of a link . I am using routing for this .
home.jsp
I am having below div outside the ng-view directive .If I am putting this inside ng-view ,Page is not working properly .I dont know if it should be inside or outside .
<div>
<h4> <a href ="#/Mix.web" data-ng-click="getMixData()" target="_self">Overall Mix
</a></h4>
</div>
Mix.jsp
I have not put it inside ng-view .Again If I am enclosing it inside ng-view ,the page is not loading .
Controller js
var app = angular.module('myApp', []);
app.config(function($routeProvider) {
$routeProvider
.when('/home.web', {
templateUrl : 'Views/Home.jsp',
controller : 'MyController'
})
.when('/Mix.web', {
templateUrl : 'Views/Mix.jsp',
controller : 'MyController'
});
});
Few things I have debugged .
Onclick of the link , controller function is getting called and subsequent java spring controller is sending data successfully as well .
I am not able to figure out if this is the correct way to implement routing . What am I doing wrong here .

using multiple named views in ng-repeat

I am using angularjs with ui-router and need a dashboard pattern with this.
I have a menu and I want to open a widget on clicking this button with its content and when I click 2nd button another widget with it's content should be loaded without disturbing 1st one.
my idea was this.
Routing
$stateProvider
.state("dashboard", {
abstract:true,
url: "/",
templateUrl:partialDir+"dashbord.html",
controller:"dashboardCtrl"
})
.state("dashboard.home",{
url:"home",
views:{
'teacher':{
//teacher's partial and controller alongwith further child routes
},
'Student':{
//student's partial and controller alongwith further child routes
},
//same for employee
}
});
})
DashboardCtrl
it manages an array against click event.click on teacher in menu will send view="teacher"
this array is generating against every click correctly but i want something like this....
<ul ng-repeat="view in views|unique:'name'">
<li><ui-view="{{view.name}}"></ui-view></li>
</ul>
which is not working.
InShort I want to show multiple named views but not at once.wanna show them against click event with separate scope for each widget.
I think I have cleared my app's structure will anyone help n tell me why these named views are not working as I want.Am I doing something wrong?

how to create a page push in angularjs using the ionic framework?

I have the following structure
The idea is that when you click this item, I am taken to a page post.html
Controller:
$scope.showPost = function (index) {
$rootScope.postContent = $scope.items[index];
$scope.navi.pushPage('post.html'); //this does not work, I want to create something to take me to that page
};
HTML:
<ion-item ng-click="showPost($index)">HERE</ion-item>
Define a route (See http://angular-ui.github.io/ui-router/sample/#/)
Then inject $state in your controller declaration and do :
$state.go('post.html')
PS : populating the rootScope is generally a bad practice.

Resources