I'm tring build single page app, but i have problem with angular routing it doesnt work.
I'm using spring boot, thymeleaf and angular 1.4.8.
I'm basing on this example https://code.angularjs.org/1.4.8/docs/api/ngRoute/directive/ngView
Here is my main controller:
#Controller
public class HomeController {
#RequestMapping(value = "/")
public String index(){
return "index";
}
}
Here is my index.html
<!DOCTYPE html>
<html>
<head ng-app="ngViewExample">
<title></title>
</head>
<body>
<div ng-controller="MainCtrl as main">
test
<div ng-view=""></div>
</div>
<script type="text/javascript" th:src="#{/js/lib/angular.js}" />
<script type="text/javascript" th:src="#{/js/lib/angular-route.js}" />
<script type="text/javascript" th:src="#{/js/lib/angular-resource.js}" />
<script type="text/javascript" th:src="#{/js/lib/underscore.js}" />
<script type="text/javascript" th:src="#{/js/lib/restangular.js}" />
<script type="text/javascript" th:src="#{/js/src/index.js}" />
</body>
</html>
index.js
var home = angular.module('ngViewExample', ['ngRoute']);
home.config(['$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/test', {
templateUrl: 'test.html',
controller: 'TestCtrl',
controllerAs: 'test'
})
}])
.controller('MainCtrl',
function() {
})
.controller('TestCtrl',
function() {
});
And content I wish to pass to ng-view
test.html
<div>
Hello
</div>
Everything is loading fine but routing just not working here.
you linked me this question yesterday:
here my answer so far
Let's start with How to provide static content via Spring Boot
As shown in this spring blog all resources placed in the directories
/META-INF/resources/
/resources/
/static/
/public/
inside your classpath are added as static resources. So for example just put your index.html into the /public/ directory inside your classpath and you won't need your HomeControlleranymore
Now to the angular part
First of all put the ng-app directive at the <html>or the <body> tag.
I can't see any problems with your angular code so far. Can you verify, that the partial HTML is available at the /test endpoint? If not please follow the steps i told you above. Just put the test.html inside the /public/directory inside your classpath.
Are there any errors in the console if you open the browser devtools and reload the page?
If you could provide your project on Github i will have a look at it.
First of all, Please ng-app directive placement <body> or <html> tag
<body ng-app="ngViewExample">
Template url
templateUrl: 'test'
MvcConfig.java
#Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/test").setViewName("test");
}
}
SpringBootApp
#SpringBootApplication
#ComponentScan(basePackages = {"com.example.spring"})
public class SpringAngularApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAngularApplication.class, args);
}
}
where do you put test.html. It should be in /resources/static folder. If in /resources/templates it will be process by thymeleaf and need to be added in ViewControllerRegistry
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/test").setViewName("test");
}
}
Related
I'm trying to make a single page application with a Spring back end and an AngularJS front end. I've followed tutorials and looked up similar questions but ngRoute just doesn't seem to work with a Spring back end (I got it to work with a NodeJS back end).
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Spring Demo</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.js"></script>
<script src="../static/index.js"></script>
</head>
<body ng-app="index" ng-controller="indexController">
test
<div ng-view=""></div>
</body>
</html>
test.html
<div>
Template loaded
</div>
index.js
'use strict';
const indexModule = angular.module('index', ['ngRoute']);
indexModule.controller("indexController", function indexController($scope) {
});
indexModule.config(function($routeProvider) {
$routeProvider.when('/test', {templateUrl: 'test.html'});
});
SringDemoController.java
package com.springdemo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class SpringDemoController {
#RequestMapping({ "/" })
public String getIndexTemplate() {
return "index";
}
}
I get this error when I click the link and the URL changes to http://localhost:8080/test
Here is the solution.
The Index page :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test title</title>
</head>
<body ng-app="TestApp">
<div>
<h1>The Index</h1>
<ul>
<li>
<a ng-href="#!/test"> Temp One</a>
</li>
</ul>
<div ng-view=""></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular-route.js"></script>
<script src="js/config.js"></script>
<script src="js/controller/main.js"></script>
<script src="js/controller/test.js"></script>
</body>
</html>
The Router config (its called config.js)
'use strict'
angular.module('TestApp' , ["ngRoute"])
.config(function($routeProvider){
$routeProvider
.when('/' , {
templateUrl : "view/main.html",
controller : 'MainController',
controllerAs : 'main'
})
.when('/test' , {
templateUrl : "view/test.html",
controller : 'TestController',
controllerAs : 'test'
})
.otherwise({
redirectTo: '/'
});
});
And the server-side controller for the route :
package com.testApp;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class ServerController {
#RequestMapping(value = "/test")
public String getTestTemp() {
return "static/test";
}
}
UPDATE :
actually, the method inside the ServerController is not needed. It can be written as follows
package com.testApp;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping(value = "/test")
public class ServerController {
}
So if you write any REST method in this controller, the endpoint from both client and server side will be /test/{the Name of your endPoint }
Here is the Project Structure
If you add more templates, make sure you create the routeon the client side and also the server side
I have two Spring Boot projects, Project1 and Project2. I have angular code in both the projects under 'static' folder. I am trying to route to the resources in Project2 from Project1 as below,
src/main/resources/static/index.html (in Project1)
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="app.js">
</script>
</head>
<body>
<a ui-sref="spendCar">Click here to go to Spend Cat of Project2</a>
</body>
</html>
src/main/resources/static/app.js (in Project1)
var proj1 = angular.module('proj1', ['ui.router']);
proj1.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'partial-home.html'
})
.state('spendcat', {
url: '/spendcat',
templateUrl : 'http://localhost:8090/spendcat' //calling Project2's end point
});
});
In Project2 I have a controller as below,
#Controller
#RequestMapping("/spendcat")
#CrossOrigin
public class SpendCatController {
#RequestMapping(value = "", method = RequestMethod.GET)
public String getSpendCatPage() {
return "spendcatpage"; //spendcatpage.html is under 'static' folder.
}
}
src/main/resources/static/spendcatpage.html (in Project2)
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="sc.js">
</script>
</head>
<body>
<div>Welcome to spend category page</div>
<input type="button" onclick="doClick()" value="Click Here">
</body>
</html>
I get error when "Click Here" button is clicked. If the javascript function doClick() is directly included in html file, then it works. Please suggest me how to load all resources of project2 in project1.
My Sample application has two MVC Controllers
1.HomeController
2.DetailsController
HomeController.cs
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
Home -> Index.cshtml
<div>
Home - Index
</div>
DetailsController.cs
public class DetailsController : Controller
{
public ActionResult Index()
{
return View();
}
}
Details -> Index.cshtml
<div>
Details - Index
</div>
And in the _Layout.cshtml I have links to Home and Details.
_ViewStart.cshtml
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
_Layout.cshtml
<!DOCTYPE html>
<html data-ng-app="app">
<head>
<base href="/" />
<title>Angular Routing</title>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-route.js"></script>
<script src="~/App/app.js"></script>
</head>
<body>
<h1>Layout</h1>
Home
Details
<div ng-view>
#RenderBody()
</div>
</body>
</html>
When the page loads, I get the content from _Layout.cshtml, but nothing gets loaded into the ngView container.
My guess, angular is trying to load the Home view as set in the route config for root route '/'.
But its gets back the full view with _Layout.cshtml, which again tries to load the home page and this loop goes on indefinitely.
app.js
(function () {
var app = angular.module("app", ["ngRoute"]);
app.config(config)
function config($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: "/Home",
})
.when('/Home', {
templateUrl: "/Home",
})
.when('/Details', {
template: "/Details",
});
$locationProvider.html5Mode(true);
}
}());
I get this error in the Chrome console.
angular.js:13920 RangeError: Maximum call stack size exceeded
So I tried to return Partial view from HomeController, which loaded the Home/Index view but the content in _Layout.cshtml did not load.
How to do angular routing in MVC application,is there a way to use the ngView in the _Layout.cshtml?
First of all, if you want to leverage Angular with ASP.Net MVC, you want to watch AngularJS & ASP.NET MVC Playing nice Tutorial by Miguel Castro.
You can view my sample project at GitHub.
The concept is to use MVC Route as main entry point for SPA, and then let Angular Route handle routing for individual pages. Main take away is MVC RouteConfig.cs in which you want users/{*catchall}.
FYI: in my sample project, I use MVC's cshtml as Angular View. You can ignore if you want to use regular html. In addition, I use Angular 1.5 Component so that I can convert to Angular 2 easily when it is available for production.
Trying to write a ui.router in typescript for the first time. as of now my code looks like this:
class Configuration {
constructor(private $stateProvider: ng.ui.IStateProvider,
private $urlRouterProvider: ng.ui.IUrlRouterProvider) {
this.init();
}
private init(): void {
this.$stateProvider.state("main", Configuration.defaultState());
this.$stateProvider.state("login", Configuration.login());
this.$urlRouterProvider.otherwise('/main');
}
private static defaultState(): ng.ui.IState {
return {
url: "/main"
, template: "<h1>hello</h1>"
}
}
private static login(): ng.ui.IState {
return {
url: "/login"
, template: "login"
}
}
}
angular.module('smm')
.config(($stateProvider: ng.ui.IStateProvider,
$urlRouterProvider: ng.ui.IUrlRouterProvider) => {
return new Configuration($stateProvider, $urlRouterProvider)
});
As much as the compile code looks all right, the router does not seem to work, I have no error in the console nor any route is executed. I guess the problem is silly but I can't seem to find it. Any idea?
For me is your code working as is. There is a working plunker with your code as is.
This is the index.html
<html ng-app="smm" >
<head>
<title>my app</title>
<style>ul { padding-left: 0; } li { list-style: none; }</style>
<script data-require="angular.js#*"
src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.0/angular.js"
></script>
<script data-require="ui-router#*"
src="//rawgit.com/angular-ui/ui-router/0.2.15/release/angular-ui-router.js"
></script>
<script src="script.js"></script>
<script src="Config.js"></script>
</head>
<body>
<ul>
<li>/login
<li>/main
</ul>
<div ui-view=""></div>
</body>
</html>
This is script.js:
var app = angular
.module('smm', [
'ui.router'
])
And content of the Config.js could be found here
Check the working example here
Note, with
<html ng-app="smm" ng-strict-di>
...
we would need:
angular.module('smm')
.config(['$stateProvider', '$urlRouterProvider',
($stateProvider, $urlRouterProvider) => {
return new Configuration($stateProvider, $urlRouterProvider)
}]);
Check that forked version here, and playground snippets here
I want to be able to quickly build an AngularJS application using ui-router without having to set up a server. So that I can send this folder to anyone and the application will still work.
I have tried putting a # infront of the route as adviced here. I have also tried to follow other advice related to the ngroute, but nothing seems to work and since I want to use ui-router rather than ng-route I'm not sure whether the advice is even applicable to my situation.
I have also tried to create a manifest file to store the files offline according to this page.
In firefox it kind of works but for some reason it double up what is on the index.html page. But in chrome which is my preferred browser it doesn't work at all. I get an error about a failed ajax call; why don't the manifest file download all pages straight away?
How should I accomplish building an AngularJS app with ui-router without needing a server?
Here is simple snippet of my code:
index.html
<!DOCTYPE html>
<html lang="en" ng-app="app" manifest="mycache.manifest">
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<a ui-sref="home.messages">Messages</a>
<div ui-view></div>
<script type="text/javascript" src="bower_components/angular/angular.js"></script>
<script type="text/javascript" src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<script src="js/routes.js"></script>
<script src="js/main.js"></script>
</body>
</html>
messages.html
<button ng-click="contextCtrl.getAllMessages()">Get Messages</button>
<div ng-repeat="message in contextCtrl.messages">
{{message}}
</div>
routes.js
'use strict';
angular.module('app', ['ui.router']);
//Setting up route
angular.module('app').config(['$stateProvider',
function($stateProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'index.html',
controller: 'ContextCtrl',
controllerAs:'contextCtrl'
})
.state('home.messages', {
url: '/messages',
templateUrl: 'messages.html',
controller: 'ContextCtrl',
controllerAs:'contextCtrl'
});
}
]);
main.js
'use strict';
/*jslint latedef:false*/
//Controller declaration
angular.module('app').controller('ContextCtrl', ContextCtrl);
function ContextCtrl() {
var vm = this;
vm.messages = [];
vm.getAllMessages = getAllMessages;
function getAllMessages(){
vm.messages = ['m1', 'm2', 'm3', 'm4'];
};
}
mycache.manifest
CACHE MANIFEST
js/main.js
js/routes.js
messages.html
bower_components/angular-ui-router/release/angular-ui-router.js
bower_components/angular/angular.js