I have an app that have to be customisable and one parameter is the root of the url. The app ain't necessarily at the root of the website, ie. it can be hosted at http://onedomain.com/index.html, where the appName would be /, as it can be hosted at http://anotherdomain.com/myapp/index.html, where the appName would be /myapp/.
But I need to know the appName in the router, so in the configFn of my module, to do this kind of stuff:
return $routeProvider.when(appName + "index.html", {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
As I have more parameters, I started a service I called Settings but you can't inject services while configuring a moduleā¦
What would you do?
For my concern, I started thinking about a custom provider but I'm not sure it's appropriate.
For Settings related information, I use constant:
angular.module(...)
.constant("APPNAME", "/myapp/")
.controller(..., function(..., APPNAME) {...})
Here is a simple plunker to illustrate constant.
Just use .when('/' and <base href="/myapp/" />.
Related
I have have done some research here and in general, but couldnt find a proper way to implement this.
We have and MVC/WebAPI2/AngularJS Web app.
I am trying to achive this goal: being able to put my app anywhere in IIS app folder structure without any code changes. That means, get rid of any IIS Application name in my code.
Here is a simple fragment of ng-route path defined:
.when("/", { templateUrl: "Home/Main", controller: "MainController",
controllerAs: "vm" })
Now, the IIS app is called ReportsWeb (but could be any name)
If I set ReportsWeb app under Default Web Site root:
http://localhost/ReportsWeb/
then everything works fine, and templateUrl page is loaded fine.
But if the app is placed under another IIS App (the one we have here is called RealSuiteApps, which is itself under Default Web Site)
http://localhost/RealSuiteApps/ReportsWeb/
then, the templates are not loaded, since constructed URL for templateUrl is no longer valid:
http://localhost/RealSuiteApps/Home/Main
If I change templateUrl to "/Home/Main", constructed URL is not valid again
http://localhost/Home/Main
If I change templateUrl to "./Home/Main", constructed URL is not valid again
http://localhost/RealSuiteApps/Home/Main
Is it possible to define templateUrl only relative to the latest App name in the IIS hierarchy without hardcoding all these names, so that it will work in any IIS app tree
http://localhost/App1/App2/App3/ReportsWeb/
Thanks!
I use grunt-html2js tool to convert all html templates to Javascript at build time, which uses Angular's template cache.
I've defined my grunt task to overwrite the default module naming to templates/ so that I can reference any template easily:
html2js: {
options: {
rename: function (moduleName) {
return moduleName.replace(/^.*[\/\\]/, 'templates/');
}
},
all: {
src: ['./src/**/*.html', '!./src/index.html'],
dest: 'tmp/templates.js'
}
},
This will create a templates.js file that I can include as a script tag. Then I can access any template like so:
templatUrl: 'templates/my-template-filename.html'
Regardless of where it's path was in the source code.
So, I'm pretty new to AngularJS and I'm trying to use AngularJs ngRoute in my application.
It all works smoothly when I start at the application homepage:
http://localhost:8080/appName/
And when I click on links from this point it works smoothly.
However, when I type a URL that I know exists/works, it gives me a 404 error. If I go to that link by using the application instead of the url it loads fine, even though it has the same url.
Eg. http://localhost:8080/appName/search
will give a 404, even though that is the same url that is the default redirect.
Indeed, the only url that will load by typing in the location is the base URL I mentioned above.
My app.js looks like this:
app.config( ['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider){
$routeProvider
.when("/search", {
templateUrl: "search.html",
controller: "SearchController"
})
.when("/results", {
templateUrl: "results.html",
controller: "ResultsController"
})
.when("/browse", {
templateUrl: "browse.html",
controller: "BrowseController"
})
.otherwise({redirectTo:"/search"});
//This gets rid of the # on the urls to the templates
$locationProvider.html5Mode(true);
}]);
I am hosting this on a glassfish4 server.
Is there something obvious I am missing/misunderstanding about how ngRoute works? Is there some setting that I am missing?
All help appreciated...
EDIT 1: As #Matthew Green below says, I need to configure the webserver to return the index.html for all pages below
http://localhost:8080/appName
I know I am being completely dense here, but where abouts is this configured? I am hosting the code in a MAVEN Jersey-Quickstart-Webapp.
When you use ngRoute, you are using javascript to handle routing to create a SPA. That means you need to hit a real page that loads your routing for your application to know what page to route to.
For example, your http://localhost:8080/appName/ should be routing to your index.html which would contain the javascript for your routing. With that page loaded it knows how to handle the links you have in your application. However, if you were to go directly to http://localhost:8080/appName/pageName you also need that to load index.html, as it is the one that loads your routing. Once your routing is loaded it should direct you to the correct page in your application. Without redirecting in place, http://localhost:8080/appName/pageName is not a real page and therefore correctly returns a 404.
Knowing this, the thing you have to figure out is what kind of server setup you have to configure the appropriate redirects for everything under http://localhost:8080/appName/ to go to your index.html page.
I'm creating a single page application using flask. If I understand the process correctly, then ill be having flask serve up a single page (html and css) upon the first GET request. From their, the client will only receive data and the it will use already stored html (partials/other pages) to modify the site.
Ideally, I would like to use something that provides a nicer syntax then html, something like slim, haml or jade. Though i don't need the templating aspect, as this functionality will be provided through angularJS.
Assuming the above is correct, my confusion is how to use pyjade (or any such tool) with flask to transform the partials that the client side application would be using. For example, if i have some client side code that creates the routes like so...
var app = angular.module('App');
app.config(function($routeProvider){
$routeProvider.when('/', {
templateURL: 'partials/home.jade',
controller: 'HomeController'
}).otherwise({ redirectTo: '/' });
});
Then i would need home.jade to be transformed into home.html when it was served up to the client. Assuming I understand what 'should' be done correctly, how do I do this?
One such solution would be manually transform the home.jade into home.html and keep my code like this:
var app = angular.module('App');
app.config(function($routeProvider){
$routeProvider.when('/', {
templateURL: 'partials/home.jade',
controller: 'HomeController'
}).otherwise({ redirectTo: '/' });
});
I'm using Flask, PyJade, and jQuery as a controller. You can install PyJade with,
sudo pip install pyjade
And then according to the documentation you can insert the following line in your Flask app,
app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')
I am trying to merge the Angularfire-Seed with a sample Ionic App. This has worked so far quite well.
To browse between my views, I am interested to use the ionic functionality:
// requires ui-router
<ion-nav-view></ion-nav-view>
instead of
// requires ngRoute
<div ng-view></div>
The problem is that the ion-nav-view (Ionic) is part of the ui-router (see here explanation) whereas ng-view part of ngRoute (Angularfire-seed).
Is there therefore a way to keep using the ngRoute (as a lot of coding has been done in the Angularfire-Seed project and thus I dont want to switch to ui-router), but still use ion-nav-view?
Follow-up: has someone implemented AngularFire with Ionic (and thus ui-router)? Available git?
No, ion-nav-view uses the ui-router under the hood. Unless you want to write your own implementation you can't use ngRoute with it.
EDIT
To answer your question about using your linked file with Ionic, you'll have to refactor it to use ui-router. Check the UI Router Guide here and the Ionic docs here. It's well worth reading the first link to get a thorough understanding.
Dependencies
ui-router is included in the Ionic bundle so you don't need to explicitly state it as a dependency.
So provided you already have Ionic as a dependency, instead of
angular.module('myApp.routes', ['ngRoute', 'simpleLogin'])
you can just have
angular.module('myApp.routes', ['simpleLogin'])
.config blocks
I've not used ngRoute but the syntax between the $stateProvider of ui-router look quite similar. With ngRoute you used the $routeProvider like so...
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/chat', {
templateUrl: 'partials/chat.html',
controller: 'ChatCtrl',
})
With ui-router configuring a 'state' is something like the following (the use of $urlRouterProvider.otherwise() at the end catches any URLs that haven't been explicitly defined and redirects to whichever URL you specify)
.config(function($stateProvider, $urlRouterProvider){
$stateProvider
.state('home', {
url: '/',
templateUrl: "partials/home.html",
controller: 'HomeCtrl',
resolve: {
// resolve stuff in here, check the docs for implementation differences
}
})
.state('chat', {
url: '/chat',
templateUrl: "partials/chat.html",
controller: 'ChatCtrl',
}
})
$urlRouterProvider.otherwise('/');
Authentication is handled in your linked file, this link may help angular ui-router login authentication. Good luck!
When enabling the html5Mode in AngularJS via $locationProvider.html5Mode(true), navigation seems to be skewed when you land on a page deeper in the site.
for example:
http://www.site.com
when i navigate to the root, i can click all links in the site, Angular's $routeProvider will take over navigating through the site and loading the correct views.
http://www.site.com/news/archive
but when i navigate to this url (or hit refresh when I'm on a deeplink like the above one...) this navigation is not working as I expect it to.
first of all, our as the Documentation for $locationProvider.html5Mode specifies, we catch all urls on the server, similar to the otherwise route in angular, and return the same html as the root domain. But if I then check the $location object from within the run function of angular, it tells me that http://www.site.com is my host and that /archive is my path. the $routeProvider arrives in the .otherwise() clause, since i only have /news/archive as a valid route. and the app does weird stuff.
Maybe the rewriting on the server needs to be done differently, or I need to specify stuff in angular, but currently i'm clueless as to why angular see's the path without the /news segment included.
example main.js:
// Create an application module
var App = angular.module('App', []);
App.config(['$routeProvider', '$locationProvider', function AppConfig($routeProvider, $locationProvider) {
$routeProvider
.when(
'/', {
redirectTo: '/home'
})
.when('/home', {
templateUrl: 'templates/home.html'
})
.when('/login', {
templateUrl: 'templates/login.html'
})
.when('/news', {
templateUrl: 'templates/news.html'
})
.when('/news/archive', {
templateUrl: 'templates/newsarchive.html'
})
// removed other routes ... *snip
.otherwise({
redirectTo: '/home'
}
);
// enable html5Mode for pushstate ('#'-less URLs)
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
}]);
// Initialize the application
App.run(['$location', function AppRun($location) {
debugger; // -->> here i debug the $location object to see what angular see's as URL
}]);
Edit
as per request, more details on the server side:
the server side is organised by the routing of zend framework, and it handles it's own routes (for serving data to the frontend on specific /api urls, and at the end, there is a catch-all route if no specific other route is bound, it serves the same html as the root-route.
so it basically serves the homepage html on that deeplinked route.
Update 2
after looking into the problem we noticed this routing works fine as it is, on Angular 1.0.7 stable, but shows the above described behaviour in the Angular 1.1.5 unstable.
I've checked the change-logs but haven't found anything useful so far, I guess we can either submit it as a bug, or unwanted behaviour linked to a certain change they did, or just wait and see if it get's fixed in the later to be released stable version.
Found out that there's no bug there.
Just add:
<base href="/" />
to your <head />.
This was the best solution I found after more time than I care to admit. Basically, add target="_self" to each link that you need to insure a page reload.
http://blog.panjiesw.com/posts/2013/09/angularjs-normal-links-with-html5mode/
This problem was due to the use of AngularJS 1.1.5 (which was unstable, and obviously had some bug or different implementation of the routing than it was in 1.0.7)
turning it back to 1.0.7 solved the problem instantly.
have tried the 1.2.0rc1 version, but have not finished testing as I had to rewrite some of the router functionality since they took it out of the core.
anyway, this problem is fixed when using AngularJS vs 1.0.7.
Configure AngularJS
$location / switching between html5 and hashbang mode / link rewriting
Configure your server:
https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#wiki-how-to-configure-your-server-to-work-with-html5mode
My problem solved with these :
1- Add this to your head :
<base href="/" />
2- Use this in app.config
$locationProvider.html5Mode(true);