I am using spring and angular js in my project. In spring I set the view resolver as follows,
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
return viewResolver;
}
In angularjs ,I'm trying to route views/subview/test.html. Code as follows,
$stateProvider
.state("test", {url: "/test", templateUrl: "subview/test.html"});
});
Here the subview is the child folder of view folder.Since I set the view resolver to view folder only it not supports the view/subview/test.html.
Is it possible to setPrefix to all subfolders? If not, suggest other ways to handle this problem.
no you will need to set the full path each time - the path is relative to the top level html page the app is running in - you could of course use variables to manage this e.g.
var baseTemplatePath = "/WEB-INF/views/";
$stateProvider
.state("test", {url: "/test", templateUrl: baseTemplatePath + "subview/test.html"});
});
you could also put the variable in a higher level service for access everywhere.
angular.app("yourApp")
.service("pathService", function() {
return {
baseTemplatePath: "/WEB-INF/views/"
};
});
and then use (making sure you have injected the pathService):
$stateProvider
.state("test", {url: "/test", templateUrl: pathService.baseTemplatePath + "subview/test.html"});
});
Related
I am working on web application using AngularJS and have used ui.router for routing.
I have configured the app
.state('init', {
url: '/',
controller: 'LocalizationCtrl',
templateUrl: 'partials/common/init.html'
})
.state('login', {
url: '/login',
templateUrl: 'partials/auth/login.html',
controller: 'LoginCtrl',
resolve: {
skipIfLoggedIn: skipIfLoggedIn
}
});
In init I load the localization json from server
If I hit the following URL it all works fine
http://localhost/app/index.html
However if I hit the following URL or any other state directly the localization files do not load
http://localhost/app/index.html#/login
How can I make sure that when app is loaded first using any URL the localization code should execute and not bypassed.
/ Bu default go to state -
angular.module('yourModuleName').run(["$location", function ($location) {
$location.url('/');
}]);
So, when you refresh or take your web application, your site will go to url /, so it should invoke your state, init to work.
Or you can use $state to go to a state upon starts
/ Bu default go to state -
angular.module('yourModuleName').run(["$state", function ($state) {
$state.go('init');
}]);
Its very simple there is a property "Resolve" you can use that.
In your parent state you can write this -
.state('parentState', {
resolve : {
localize : function() {
//Localization code here
}
}
};
Resolve will ensure that your localization work will be done before controller is loaded.
I know this might get an answer here, however that goes more for lazy loading implementation itself.
So, this is a typical UI-Router config block:
app.config(function($stateProvider, $urlRouterProvider, $injector) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'view_home.html', // Actually SHOULD BE result of a XHR request ....
controller: 'HomeCtrl'
});
});
But what if I want to load such templateUrl when it's requested ($stageChangeStart) and it would be AJAX request based.
How should it be implemented? How are LARGE angular applications dealing with this?
We should (in this case) use TemplateProvider. Small cite from doc:
Templates
TemplateUrl
... templateUrl can also be a function that returns a url. It takes one preset parameter, stateParams, which is NOT injected.
TemplateProvider
Or you can use a template provider function which can be injected, has access to locals, and must return template HTML, like this:
$stateProvider.state('contacts', {
templateProvider: function ($timeout, $stateParams) {
return $timeout(function () {
return '<h1>' + $stateParams.contactId + '</h1>'
}, 100);
}
})
And there is even more.
We can use cooperation with really powerful
$templateRequest
In this Q & A (Angular UI-Router dynamic routing based on slug from API Ajax Call. Load view based on slug) we can see so simple templateProvider defintion
.state('hybrid', {
// /john-smith
url: '/:slug',
templateProvider: ['type', '$templateRequest',
function(type, templateRequest)
{
var tplName = "tpl.partial-" + type + ".html";
return templateRequest(tplName);
}
],
and the result is also chached...
There are some other links to similar Q & A, including working examples
Angular UI Router: decide child state template on the basis of parent resolved object
Angular and UI-Router, how to set a dynamic templateUrl
I am trying to create a link in my template angularjs by doing something like:
<a ng-href="/#!/content/[[value.id]]">[[key]]</a>
But I am wondering myself if is possible do something like symfony2 does, example:
routing.yml
home_redirect:
path: /
defaults:
_controller: FrontendBundle:Controller:function
path: /home
permanent: true
options:
expose: true
And using it in your twig template by doing:
one link to home
That is really, really helpful because I don't have to "hardcode" all my routes.
To ensure a proper routing, you can use ui-router.
Here is an exemple on plunker
How this works :
1 - Follow the installation guide on their github
2 - Write your state definition :
app.config(function($stateProvider, $urlRouterProvider){
//If no route match, you'll go to /index
$urlRouterProvider.otherwise('/index');
//my index state
$stateProvider
.state('index', {
url: '/index',
templateUrl: 'index2.html',
controller: 'IndexCtrl'
})
//the variable state depending on an url element
.state('hello', {
//you will be able to get name with $stateParams.name
url: '/hello/:name',
templateUrl: 'hello.html',
controller: 'HelloCtrl'
})
});
3 - Write links by their state name :
//add this directive to an html element
//This will go to /index
ui-sref="index"
//This will go to /hello/
ui-sref="hello"
//This will go to /hello/ben
ui-sref="hello({name:'ben'})"
//This will go to /hello/{myname}
ui-sref="hello({name:myname})"
4 - Get the param into your controller :
//inject $stateParams
app.controller('HelloCtrl', function($scope, $stateParams){
$scope.controller = "IndexCtrl";
//get the param name like this
$scope.name = $stateParams.name;
});
Hope it helped. Also keep in mind the ui-router got some really powerful tools such as resolve and nested state/view. You'll probably need theses now or later.
PS : If the plunker don't work, just fork it and save again.
You could do this :
'use strict';
angular.module('AngularModule')
.config(function ($stateProvider) {
$stateProvider
.state('YourStateName', {
url: '/your/url',
views: {
'aViewName': {
templateUrl:'views/components/templates/yourTemplate.html',
controller: 'YourController'
}
},
resolve: {
}
});
});
// then in your controller
angular.module('AngularModule')
.controller('MyController',function($scope, $state){
$scope.goTo = function(){
$state.go('YourStateName');
}
}
);
//in your html make sure the <a> tag is in scope with the 'MyController'
<a ng-click='goTo'>[[key]]</a>
or
you can just do this :
<a ng-href="/your/url"></a>
that way you bypass the controller you can still put logic in the controller that was specified in the state
I'm making a single page application (SPA). I made a controller called InitialControler to load the data from the server at this url (local.app/init).
I want this url to be opened before any other url. I'm using ui-router, I did a $state.go('init') in the .run() function but it still load the requested page before the 'init' page
First create state called app
$stateProvider.state('app', {
abstract: true,
templateUrl: "assets/partials/container.html",
controller: 'AppCtrl',
resolve: {
init: function(MyFactory) {
return MyFactory.resolver();
}
}
});
Now, any new state you create should be child state of app state. This is also good because it become sort of your root scope. And state will not process unless your factory resolves.
This is how you create your factory
app.factory('MyFactory', function($http){
var items = [];
return {
resolver: function(){
return $http.get('my/api').success(function(data){
items = data;
})
},
get() {
return items;
}
}
});
Now in any other state
$stateProvider.state('app.items', {
url: '/items',
templateUrl: "assets/partials/items.html",
controller: function($scope, MyFactory){
$scope.items = MyFactory.get();
}
});
More on sate resolve
https://github.com/angular-ui/ui-router/wiki#resolve
If you are using ui-router then you could resolve this using nested states. For example:
$stateProvider
.state("main", {
url: "/",
template: '<div ui-view></div>',
controller: 'InitController'
})
.state("main.landing", {
url: "landing",
templateUrl: "modules/home/views/landing.html",
controller: 'LandingPageController'
})
.state("main.profile", {
url: "profile",
templateUrl: "modules/home/views/profile.html",
controller: 'ProfileController'
});
In this example you have defined 3 routes: "/", "/landing", "/profile"
So, InitController (related to "/" route) gets called always, even if the user enters directly at /landing or /profile
Important: Don't forget to include <div ui-view></div> to enable the child states controller load on this section
One way to do is, in config declare only 'init' state. And in InitialController, after data is loaded(resolve function of service call), configure other states. But in this approach, whenever you refresh the page, the url will change to local.app.init.
To stay in that particular state even after reloading, the solution I found is to have a StartUp app in which I loaded the required data and after that I bootstraped the main app manually by angular.bootstrap.
I have an MVC 5 app with areas and I am trying to use the ui-router for AngularJs within one of my areas but I noticed that the templateUrl is wrong. It is trying to use a relative path but since I am using MVC routes and an Area the path to the template is incorrect.
The url to my area controller action is localhost:3789/Admin/UserManager .
The actual path is /Areas/Admin/Scripts/app/usermanager/partials/userlist.html .
angular.module("bsAdmin.userManager", ["ngResource", "ui.router", "ui.bootstrap", "bsPromiseTracker", "bsBusy", "angular-growl", "ngAnimate"])
.config(function ($stateProvider, $urlRouterProvider) {
// default state
$urlRouterProvider.otherwise("/userlist");
$stateProvider
.state('userlist', {
url: "/userlist",
templateUrl: "partials/userlist.html"
});
});
Angular ui-router tries to load the partial template using localhost:3789/Admin/partials/userlist.html
What are some techniques I can use so that the script will use the correct url to load the partial?
If your Angular javascript is in your .cshtml file, you can use the ASP.NET MVC URL helper to build the URL.
$stateProvider
.state('userlist', {
url: "/userlist",
templateUrl: "#Url.Content("~partials/userlist.html")"
});
});