I want to pass two values to new ui-view via params:
item id
list of objects
However, I'd like the new view to show only the id in the browser URL and not the stringified array of objects:
http://www.myapp.com/#/my-view/4
INSTEAD OF
http://www.myapp.com/#/my-view/4?flskdjalfjaewoijoijasdlfkjösldakjföliwejöorijo
Is it possible to either a) pass the array of objects hidden to the ui-view or b) pass both but hide the other from the browser URL?
I found something about the squash parameter, but couldn't get it to do what I'm trying.
Here's my view:
$stateProvider
.state('show', {
url: "/show/{itemId}?{itemList}",
views: {
'mainView': {
templateUrl: 'views/itemView.html',
controller: 'showController',
params: {
itemList: {
value: null,
squash: true
},
itemId: -1
}
}
}
How can I hide the list of objects from the URL, without hiding the id?
You are on the right path. To hide params you have to define them in params as you do, without squash.
Your example should look like:
$stateProvider
.state('show', {
url: "/show?itemId",
views: {
'mainView': {
templateUrl: 'views/itemView.html',
controller: 'showController'
// params do not work here! They need to be attached below ...
// $stateProvider.state('show', {url:'/show/:url_param',views:{}, params: {}})
}
},
resolve: {},
params: {
itemList: {
value: null
}
}
})
See example: http://plnkr.co/edit/wEjwCVWMKTyuSdyLr0og?p=preview
It's also possible doing that
SomeController:
$state.go(someState, {
'itemId' : item._id,
'itemName' : item.title
});
SomeRoute
function someRoute($stateProvider) {
$stateProvider
.state('someState', {
url : '/:itemName',
params : {
'itemId' : null //hides itemId param
}
});
}
Output: .../itemnumber1
Related
I am new to AngularJS.
I am sending a JsonObject to another state.
Ex:
viewScope.edit=function(d) {
var viewData = {
'name' : d.name,
};
$state.go('edit', {'viewD': viewData}, {reload: true});
};
My State is-
viewApp.config(function($stateProvider){
$stateProvider
.state('edit', {
name: '#/edit',
url: '/register/{viewD}',
templateUrl: function(){
return path+'/register.jsp';
},
controller:'registerCtrl',
resolve : {
loadPlugin: function($ocLazyLoad) {
return $ocLazyLoad.load([{
name : 'registerApp',
files: [path+'/resources/js/register.js'],
}])
}
}
})
});
In register Controller getting data-
regApp.controller('registerCtrl',function($stateParams){
if($stateParams != undefined){
console.log($stateParams.viewD);
}
});
On console output is- [object object]
How can i access the name key from this [object object].
console.log($StateParams.viewD.name); // Not Working
JSON.parse, JSON.stringify not working.
You have to change your state config URL from
url: '/register/{viewD}',
to
url: '/register/{viewD:json}',
The JSON parameter type has been added in version 0.2.13
Change your config method as following,
viewApp.config(function($stateProvider){
$stateProvider
.state('edit', {
name: '#/edit',
url: '/register',
params: {
viewD: null
}
templateUrl: function(){
return path+'/register.jsp';
},
controller:'registerCtrl',
resolve : {
loadPlugin: function($ocLazyLoad) {
return $ocLazyLoad.load([{
name : 'registerApp',
files: [path+'/resources/js/register.js'],
}])
}
}
})
});
And then you can access your object from $state like this in the controller,
$state.params.viewD or from $stateParams like this $stateParams.viewD
Now try console.log($state.params.viewD.name)
.state('profiledet', {
url: '/profiledet',
params: { 'profile_id': null},
templateUrl: 'templates/profile-det.html',
controller: 'profiledet'
})
above is the route of my page.
$cordovaDeeplinks.route({
'/profiledet': {
target: 'profiledet',
parent: 'profiledet'
}
})
this is the deep linking route, I can't pass data through this. Can anyone help me?
I have got the answer, below is the code.
$cordovaDeeplinks.route({'/profiledet:profile_id': {
target: 'profiledet',
parent: 'profiledet'
}
})
I want to have an optional url segment for the following example:
url: "/post/:category/:subcategory/:title/{id:int}",
In the above example subcategory is optional. For example it will accept:
url: "/post/sports/football/some-title/10",
and it will also accept:
url: "/post/sports/some-title/15",
which do not have subcategory. I can do that using to separate states but is there any rule for that?
Please note only subcategory segment is optional. Others are mandatory.
.state('post', {
url: '/post/:category/:subcategory/:title/:{id:int}',
templateUrl: 'views/post.html',
controller: 'postCtrl',
params: {
subcategory: { squash: true, value: null },
}
})
For more info read the doc
Solution is in detail described here
Angular js - route-ui add default parmeter
and here is how we can define such parameter:
.state('state', {
url: '/:category/{subcategory:(?:football|tennis|hokey)}/:title/:id',
abstract: true,
template: '<div ui-view=""></div>',
params: {subcategory : { squash : true, value: 'football' }}
})
I'm having a recurrent problem with my angular app whereby it doesn't refresh the page after data has been added, edited or removed. So if I add a new item to a list of subjects, the new item doesn't appear on the list unless I navigate away from the page and then come back to it. I've tried using route.reload and then resetting the scope of the subjects list below. I put in an alert to see if it get fired- but the alert appears before the page redirects back to the list of subjects, which is strange as $location.path('/subjects') is two lines before it. Here's my controller:
angular.module('myApp.controllers')
.controller('SubjectEditCtrl', ['$scope', '$routeParams', 'SubjectFactory', 'SubjectsFactory', '$location', '$route',
function ($scope, $routeParams, SubjectFactory, SubjectsFactory, $location, $route) {
// callback for ng-click 'updateSubject':
$scope.updateSubject = function () {
//Performs an update to the server
SubjectFactory.update($scope.subject);
//Redirects to list of all subjects
$location.path('/subjects/');
//Should reset the scope of the subject list
$scope.subjects = SubjectsFactory.query();
//Should reload the page
$route.reload();
//For debugging- the alert appears BEFORE the redirect to list of all subjects happens
alert('route reload happening');
};
SubjectFactory.show({id: $routeParams.subjectId}).$promise.then(function(subject) {
$scope.subject = subject;
}, function(err) {
console.error(err);
});
}]);
Can anyone suggest a solution?
EDIT: Subjects Service
var app = angular.module('myApp.services');
app.factory('SubjectsFactory', function ($resource) {
return $resource('https://myapiurl.com/subjects', {}, {
query: { method: 'GET', isArray: true },
create: { method: 'POST' }
})
});
app.factory('SubjectFactory', function ($resource) {
return $resource('https://myapiurl.com/subjects/:id', {}, {
show: { method: 'GET', isArray: false },
update: { method: 'PATCH', params: {id: '#id'} },
delete: { method: 'DELETE', params: {id: '#id'} }
})
});
Some times you need to apply changes to scope this is done by the following code:
$scope.$apply();
But this can be done only if it's not in "$digest" phase, otherwise it will throw exception. So you need to check first it's not in "$digest" phase then you can apply it. Here is the example of the code I use for safe applying changes:
safeApply: function (scope, callback) {
if (scope.$$phase != '$apply' && scope.$$phase != '$digest' &&
(!scope.$root || (scope.$root.$$phase != '$apply' && scope.$root.$$phase != '$digest'))) {
scope.$apply();
}
if (angular.isFunction(callback)) {
callback();
}
}
I can suggest next way:
You can't get data from database, after adding, you can easly push new added object to $scope.items.
Example:
$scope.add = function (newItem) {
DataService.addItem(newItem).then(function(){
$scope.items.push(newItem);
//or for removing
//$scope.items.splice($scope.items.indexOf(newItem), 1);
});
};
And adjust your factory:
addItem: function (newProject) {
$http.post('Api/Controller/Post').then(function(successResult){
...
}, function (errorResult) {
...
});
}
Item will be added in $scope.items only after success calling of server-side method.
Changing the structure of the requests slightly fixed the problem- so instead of
$scope.updateSubject = function () {
SubjectFactory.update($scope.subject);
$location.path('/subjects/');
$scope.subjects = SubjectsFactory.query();
$route.reload();
};
It is now
$scope.updateSubject = function () {
SubjectFactory.update($scope.subject).$promise.then(function (subject) {
$scope.subject = subject;
$location.path('/subjects/');
$route.reload();
}, function (err) {
console.error(err);
});
};
i am not able to navigate from one view to another view with pararameter
from :-
ViewModel : App/Foldername/page1.js
View : App/Foldername/page1.html
i want to go with id parameter:
ViewModel : App/Foldername/page2.js
View : App/Foldername/page2.html
in page1.js i wrote following things,
self.goTopage2 = function (id) {
router.mapRoute('Foldername/page2/:id', 'viewmodels/Foldername/page2', 'This is page2view');
};
in shell.js
function boot() {
router.mapNav('home');
router.mapNav('details');
router.mapNav('Foldername/page2');
log('Hot Towel SPA Loaded!', null, true);
return router.activate('home');
}
please guid me correct way!
A common approach is to have a list of routes somewhere and load up that list. When you define a list such as below, you need to use router.map() to map the routes, as mapNav creates a default route without parameters. Example of an object containing routes -
var routes = [{
url: 'home',
moduleId: 'viewmodels/home',
name: 'Home',
visible: true,
settings: {}
}, {
url: 'events',
moduleId: 'viewmodels/events/events',
name: 'Events',
visible: true,
settings: {}
}, {
url: 'eventdetails/:id',
moduleId: 'viewmodels/events/eventdetails',
name: 'Event Details',
visible: false,
settings: { event: true, show: false }
}];
And how to map those routes -
router.map(routes);
And finally how to visit those routes -
router.activate('home');
or
var url = '#/fighterdetails/' + selectedFighter.id();
router.navigateTo(url);
(DurandalJS 1.2.0) I'm not totally sure if this is the best way, since I'm quite new to Durandal, but at least managed to make it work with this:
In main.js:
router.mapRoute('details/:id', 'viewmodels/details', 'Details', false);
In list.js:
loadDetails: function (id) {
router.navigateTo('#/details/' + id);
},