using ui.router to dynamic load pages - angularjs

I'm a newbie in AngularJS, and I was using ui.router.
What I am trying to do is load html from different portals, like:
/s3/home
/goo/home
/gle/home
All prefix like s3, goo, gle are from backend, I have to get it first then load my pages, any idea for this, any way to put a variable in relative path, like
/{{portal}}/home
Mockup for expression:
angular.module('app')
.config(function ($stateProvider) {
$stateProvider
.state('{{portal}}.home', { //portal from backend
url: '/',
views: {
'content#': {
templateUrl: 'scripts/app/{{portal}}/home.html', //portal from backend
controller: 'MainController'
}
}
});
})
Find a way to do it, dynamic templateURL will do the same thing
http://fredparke.com/blog/angularjs-directive-dynamic-template

I want to use it in Javascript, is it possible
No i'm afraid not. Use Curly braces to bind expressions to elements in your html. I think you need to rethink more fundamentally your application and why you want to have "variable" template urls in such a way. Try and read up on REST as that's probably what you want to have for your backend. The frontend can then parameterise requests via url/query parameters

Related

From 1 to 3 controllers in Angular

I'm new to angularJS so I'm still learning the "angular way" of doing things and therefore seek for advice.
I started building my login/register/forgotten_password views which now work perfectly fine. So the routing looks basically like this:
mainApp.config(function ($routeProvider) {
$routeProvider
.when('/login',
{
controller: 'loginCtrl',
templateUrl: 'views/login.html'
})
.when('/register',
{
controller: 'registerCtrl',
templateUrl: 'views/register.html'
})
.when('/dashboard',
{
controller: 'dashboardCtrl',
templateUrl: 'views/dashboard.html'
})
})
Now here's the problem and/or question I have :
After a successful login, you get redirected to the dashboard which gets loaded into ng-view. The dashboard is indeed the view but there should be more controllers and templates once you enter the app (sidebar, topbar, chat...).
How would you approach this ?
I also have a globalCtrl on the html element to handle other things, just in case that information might be helpful in any way.
You shouldn't think in controllers anymore. Rather think in "components". There are lots of articles on the internet on how to learn this (better) approach. Here is one to start: Refactoring Angular Apps to Component Style
tl;dr; Create a component (element directive) for every section/part of your view. In your case a <dashboard>, <sidebar>, <topbar>, ...
You can (and should) route to components! See this issue for more information. Here is a "real life" example on how to achieve this: https://github.com/ui-router/sample-app-ng1
This is the con giving of using $routeProvider in Angular JS. When you use a $routeProvider to define routes in angular JS, a single route can only point to a single view and there is no concept of nested views using $routeProvider.
And when you talk about having more than one template inside the view, you are talking about having nested views inside a single view. Unfortunately Angular's $routeProvider doesn't provide that. But now comes the ui-router, which replace the concept of route with states. You can define multiple sub states in a state and each sub state can point to different template. Look at the following link and follow simple steps to power up views and nested views in your app.
ui-router

How to use angularjs config block?

I am new to angularJS and trying to learn it. I came across config function
where I see two different arguments as in below example.
Example 1
dashboardApp.config(function($stateProvider, $urlRouterProvider) {
//$urlRouterProvider.when('', '/add');
$stateProvider.state('add',
{
url:'/add?month&year',
templateUrl: 'partial/add.html',
controller: 'AddListController'
})
});
Example 2
gm.config(['$routeProvider', 'Path', function($routeProvider, Path) {
$routeProvider.when('/login', {
templateUrl: Path.view('application/authentication/login.html'),
controller: 'authController'
});
}]);
In the first example, config has a function parameter. And in second example config has array parameter.
Can someone please explain to me what is the difference between these two approaches and when to use which?
There are two differences here. The first example is providing configuration for Angular UI Router, whereas the second is using ngRoute.
The difference in syntax that you noted is the difference between having code that will not withstand minification (first example) and code that will withstand minification.
+1 to the previous answer pointing out $stateProvider is angular ui-router syntax. I would also point out that declaring $routeProvider has different syntax than other angular items like services and controllers.
You should use ui-route provider as it is better than ngRoute,
ui-router allows you to code your templates in a nested form

Unable to route non existing paths in Angularjs

I am unable to route the path code/:code in my website. I receive the following error:
Firefox can't find the file at /C:/Code/dola/mobileweb/app/code/123
default.htm is located in the app folder.
I am using the mobileangularui framework. I have the following routes declared (among others):
app.config(function ($routeProvider) {
$routeProvider.when('/', { templateUrl: 'codeview.htm', reloadOnSearch: false });
$routeProvider.when('/code/:code', { templateUrl: 'codeview.htm', reloadOnSearch: false });
});
Everything works fine, except when I try e.g. code/12345.
This route is intended for a call from outside, e.g. www.mywebsite.com/code/12345.
I see two issues. First is re-declaring the $routeProvider unnecessarily. The second is you don't have an "otherwise" clause to catch everything you aren't already.
Also, not an error, but good practice to follow; you are missing a controller and controllerAs explicit directive for each entry. Try this:
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'codeview.htm'
, controller: 'HomeController'
, controllerAs: 'vm'
, reloadOnSearch: false
})
.otherwise({
redirectTo: '/'
})
});
This was based on the assumption that '/code/:code' is not its own page. The option is easy to add/change if this is not the case, following the above model.
Hope this helps.
-C§
-edit-
It looks as though the best way to do this (as with what I've done in my current project for such needs) is to store the code into a global (model) variable and call the redirect using $location.path('/');. Something like the below would be part of the click-function:
DataService.code = vm.code; //the code value selected
$location.path('/');
And the resulting page would have as part of its initialization routine:
vm.code = DataService.code; //retrieves the code from memory
//and uses it to populate the page appropriately
I'm unfamiliar with how to specify a URL and have it read what page it should populate based on the trailer, aside from using PHP to catch the URL extension with the index and a $_GET redirection process. I know this can be achieved using AJAX or a Jquery catch, but I'm still somewhat new to JavaScript as a whole and not sure what the process would look like.
Alternatively, you could designate a page for each possible code (ex: 12345.html || 12345.php).
Hope this also helps.
-C§

AngularJS routing with ng-view relative to HTML page

I am quite new to Angular and now trying to make a simple routing with it. I have my landing page, currently called index2.html, containing some .js and .css includes and a div containing <ng-view></ng-view> where my content should go into.
My app.js looks like this:
var module1 = angular.module('module1', ['ngRoute']);
module1.config(function($routeProvider, $locationProvider){
$routeProvider.when("/",
{
templateUrl: "page1.html",
controller: "uiCtrl"
}
).when("/:param",
{
templateUrl: "page1.html",
controller: "uiCtrl"
}
).when("/transactions",
{
templateUrl: "page2.html",
controller: "uiCtrl"
});
});
But actually this does quite confusing things. Calling http://myurl.com/index2.html, the content of page1.html is properly loaded into the ng-view. So far, so good, but calling index2.html/123 gives my a Not Found instead of interpreting 123 as a parameter. I don't know why, but to make 123 a paremeter i have to call index2.html#123, which works, but then instantly updates the url to index2.html#/123.
Calling index2.html/transactions doesn't work at all. How can i call my /transactions route?
EDIT: If this is useful, i am using JQueryMobile as well in these pages.
I finally got what I want by getting the HTML5 mode work, which makes things so much easier.
After setting $locationProvider.html5Mode(true); I had to re-configure my webserver, what I wasn't able to manage until I found this nice guide: https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode
Now I can access each of my routes at the conventional way using a slash. Parameters can be passed with ? and &, as usual and I don't need to grapple with confusing hashtags and self-changing url's anymore.

Accommodating multiple states through $stateprovider in one $resource in angularjs?

I have a requirement where the angularjs states for one particular page would be different. Say, /items/create and /items/list -- those 2 are my urls for 2 different states. Now, how do I accommodate them in one $resource? Is it possible? Or do I have to create 2 $resource or 2 factories?
<angular module>.config(['$stateProvider', function($stateProvider){
$stateProvider
.state('items', {
url: '/items/create',
templateUrl: '<view>'
})
.state('items.List', {
url: '/items/list',
templateUrl: '<view>'
});
}]);
<angular module>.factory('Items', ['$resource', function($resource){
return $resource('/items');
}]);
Now this will not work, as the state urls are different. If i make the resource with /items/create, the first url will be executed and if make the resource with /items/list the second will be executed.
I need to make a resource which will refer to both of the states provided in the state provider. Is it possible?
Please note, I want to have them called at the page load itself before making any manual state transfer.
It's ugly but you could make the resource url /items/:state and then pass in a state property when you call Items.query/get/post
Items.post({state:"create"});
Items.get({state:"list"});

Resources