I'm trying to integrate Spring MVC4 + Angular JS but i have some problems to load template from AngularJS side. On the net there are a lot of resources, but IMHO a bit confused.
Right now i've setup a simple controller that render a page under webapp/WEB-INF/jsp. This works fine but when in this page i try to load js (angular library) i got error (resource unavailable).
I've added this to my view.jsp and resource is not loaded:
<script src="resources/js/angular/angular.js"></script>
I'm my dispatcher-servlet.xml i have the follow configuration:
<mvc:annotation-driven />
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<mvc:resources mapping="/resources/**" location="/resources/" />
To load correctly my angular library, i have to use c tag library, why ?
<script src="<c:url value="/resources/js/angular/angular.js" />"></script>
Next on it, i have created a template under webapp/WEB-INF/jsp/templates/main.jsp and i'm trying to load it using $routeProvider (i've tried to load main.jsp too, but the error is the same - resource not found)
angular.module('MyApp', ['ngRoute'])
.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'templates/main'
});
});
My answer is:
How i can load "library" without using c taglib ?
What i have to add to my configuration to load templates from AngularJs ? (using templateUrl) ?
Thanks a lot!
Related
I try to create a React app inside visualforce page via lightning. When I click preview in visualforce setting, everything is fine.
But when I use it in Lightning app builder it does not work. It shows
The error: Refused to frame 'https://mirage-video-dev-ed--ltng.container.lightning.com/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors https://mirage-video-dev-ed--c.visualforce.com".
Also really weird that if I right click and choose "Reload frame", it works.
Visualforce code
<apex:page >
<apex:includeLightning />
<div id="hello" />
<script>
$Lightning.use("c:myFirstApp", function() {
$Lightning.createComponent("lightning:container",
{ src: "{!$Resource.hello + '/index.html'}"},
"hello",
function(cmp) {
console.log("created");
// do some stuff
}
);
});
</script>
</apex:page>
myFirstApp
<aura:application access="global" extends="ltng:outApp">
<aura:dependency resource="lightning:container"/>
</aura:application>
Is there a way to fix it? I cannot find the way to load aura:application directly so if there is a way please show me.
You've got a bit of a inception problem going on... You just need to mount your react app directly inside of the VF page. No need to use a lightning:container.
See my B.A.S.S. project. This is proven to work and be extremely scalable.
Example VF Page with react app:
<apex:page showHeader="true" sidebar="false" standardStylesheets="false" docType="html-5.0">
<script type="text/javascript">
//rest details
const __ACCESSTOKEN__ = '{!$Api.Session_ID}';
const __RESTHOST__ = '';
</script>
<div id="root"></div>
<!-- Your react entry point -->
<script type='text/javascript' src="{!URLFOR($Resource.app, 'dist/app.js')}"></script>
</apex:page>
It is also possible to to run a React App directly inside a LWC, although no recommended.
See image
=>Layout1 master page which include ng-view in that i used angular routing.
=>Layout2 login.cshml page when I tried to call login page
http://localhost:1395/admin/home/Login
this login page included in ng-view which i donot want
its total different page Login.cshtml
I called this page like
Log out
when I tried url directly in address bar like http://localhost:1395/admin/home/Login
it works fine see image
but i tried from master panel to login page it shows wrong see first image
example code
master.cshtml
<html>
<body>
<div>Layout 1</div>
<div ng-view></div>
</body>
</html>
contact.html
<div ng-controller="contactcontroller">
Contact Page
</div>
help.html
<div ng-controller="helpcontroller">
Help Page
</div>
routing code
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/admin/home/contact", {
templateUrl : "contact.html",
controller: "contactcontroller"
})
.when("/admin/home/help", {
templateUrl : "help.html",
controller: "helpcontroller"
})
});
Login.cshtml
<html>
<body>
<div>Layout 2</div>
///Login code
</body>
</html>
when I call this url admin/home/help and admin/home/contact pages included in ng-view but when I call admin/home/login i donot want this include in ng-view it is separate header and footer . I want call as separate page
Thanks in advance
It is hard to understand this, but I'll take a shot at answering the question.
Your problem is probably unrelated to angularjs, what it seems to me is, that you're probably using ASP.NET MVC and your Login action is rendered inside the master layout. Basically you need to render the page without the template. See this question and answers there: Razor View Without Layout
I will also point out that angular is used for single page applications and it is hard to mix angular and ASP.NET MVC routing. You should probably decide which routing you will use. Sure, you can use .NET and initialize angular in every page, but I don't recommend this. If you can, build all your pages in angular and then then use ASP.NET Web API as a back-end.
Also you don't need to use ng-controller attribute when you use routing and specify controller.
I have been following the AngularJS tutorials on CodeSchool.
So I have views/index.html which contains all of my boilerplate code that is identical for each page. Then my templates for each page are in views/templates/ which I want included in the index.html page. So when the home page loads, it loads the views/index.html and includes the views/templates/index.html.
views/
index.html
templates/
index.html
contact.html
about.html
Currently I have
<div id="menu">
<a id="menu_home" href="/#/index" ng-click="menu.set(0)" ng-class="{current:menu.isSet(0)}">Home</a>
<a id="menu_hire" href="/#/hire" ng-click="menu.set(1)" ng-class="{current:menu.isSet(1)}">For Hire</a>
<a id="menu_info" href="/#/info" ng-click="menu.set(2)" ng-class="{current:menu.isSet(2)}">Info</a>
</div>
<div id="main">
<ng-view></ng-view>
</div>
which works great. So only the required html is requested and inserted into the page.
But my problem is that the URL doesn't change in the browser. So if a user went directly to mysite.com/contact it wouldn't work. How can I load the page correctly if the mysite.com/contact or mysite.com/about pages are accessed directly?
I have also got it working using the ngRoute module, but the same issue remains when a user goes directly to a page.
Thanks.
You should use ngRoute and $routeProvider similar to the following.
var navigationRoutes = angular.module('navigationRoutes', ['ngRoute']);
/**
* Load routes for navigation using ngRoute
*/
navigationRoutes.config(function ($routeProvider) {
$routeProvider
.when('/index', {
templateUrl: 'app/components/index/index.view.html',
controller: 'IndexCtrl'
})
.when('/contact', {
templateUrl: 'app/components/contact/contact.view.html',
controller: 'ContactCtrl'
})
.otherwise({
redirectTo: '/dashboard'
});
});
This way you can also specify a different controller based on the URL.
UPDATE
In your index page if you add -
<div class="view">
<div ng-view></div>
</div>
To your main index.html page the the contents of the $routeProvider selected file will be shown within this div. You just need to make sure that you add the tag for the controller.js files in the index.html page.
You will need to make these settings in the web server to redirect all urls to your index page where you load your angular app which in turn will handles the routes
When using html5mode(true) views are not loading on page refresh in angular.js
<base href="/">
<div ng-app="directives" >
Home
about
contact
<div ng-view></div>
</div>
in config
directives.config(["$routeProvider","$locationProvider",function($routeProvider,$locationProvider){
$routeProvider.when("/",{
templateUrl:"directives/home.html"
}).when("/home",{
templateUrl:"directives/about.html"
}).when("/about",{
templateUrl:"directives/contact.html"
}).when("/contact",{
templateUrl:"directives/about.html"
}).otherwise({
redirectTo : "/"
})
$locationProvider.html5Mode(true).hashPrefix("!")
}])
http://127.0.0.1:58552/about
not rendering the proper view.
That's one of the drawbacks of using html5Mode(true).
Basically you server can't find the resource as there is none under that URL. The address is controlled by Angular and at the point, Angular hasn't kicked in to control the pages and URLs and stuff.
The solution I found for this problem was to set up an URL rewrite (http://httpd.apache.org/docs/2.0/misc/rewriteguide.html) on my Apache server to clean up the URLs and remove the html5Mode(true).
I would like to integrate Spring MVC with Angular JS without any Template Engine
I checked a few answers, but I could not resolve it . Below I have listed Xml,Controller and Html files. What I am missing here exactly?
app-Servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<annotation-driven />
<context:component-scan base-package="com.angular.app" />
<resources mapping="/views/**" location="/WEB-INF/views/" />
<resources mapping="/resources/**" location="/resources/" />
<beans:bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<beans:property name="order" value="1" />
<beans:property name="mediaTypes">
<beans:map>
<beans:entry key="html" value="text/html" />
</beans:map>
</beans:property>
</beans:bean>
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="order" value="2" />
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value="" />
</beans:bean>
</beans:beans>
Controller
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate);
return "home.html";
}
#RequestMapping(value="/app/welcome",method = RequestMethod.GET)
public #ResponseBody String welcome() {
logger.info("entering into original controller");
System.out.println("entering into original controller");
String text="Hello World!!!! Welcome";
return text;
}
home.html
<html>
<head>
<script
src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
</head>
<body>
<div ng-app="">
<div>
Name: <input type="text" ng-model="name">
</div>
<p ng-bind="name"></p>
<div ng-controller="helloworldcontroller">
<h1>{{title}}</h1>
</div>
</div>
<script>
function helloworldcontroller($scope, $http) {
$http.get("http://localhost:8080/app/welcome").success(
function(response) {
$scope.title = response;
alert("sucess");
});
}
</script>
</body>
</html>
I'm working on some projects using the architecture Spring MVC + AngularJs and can give you feedback about:
You are trying to control the routes of html pages through the Spring MVC Contollers and I think this is not the best approach, since the AngularJs has its own engine to control routes and pages through the ng-route or ui-router.
In architectures of my projects work with a Spring MVC project providing a whole REST API to be consumed by a web AngularJs application.
The project structure is as follows:
parent-maven-project:
|_project-core: Have all bussiness logic, data source config, persistence config, Services, Repositories, Entities, etc.
|_project-web: Have a angularJs App (that controls the html pages routing using ui-router), API REST (Spring MVC Controllers) to be consumed and give the business layer access (project-core).
|_project-ear: Pack core and web projects to deploy on JBoss EAP 6.2
In Spring MVC REST layer (project-web) | set up a Spring OAuth2 server that is used to authenticate users and make the session & access control through Spring Security. When the user logs into the application, the angularjs application receives an access token Bearer that is used to make the user requests during all the time that he remain logged in. All REST services are in request scope, are stateless, then the token is used to retrieve the Spring Security session and make all user access validation.