Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mixing Spring MVC with Angular.JS

I want to make a Single Page Application with my Spring MVC Backend. I've just learnt Angular.js.

I have a left menu consisting of two links.

One makes request to the below controller. This controller makes url forwarding and lists details of something which is filled by the given model attributes.

@RequestMapping(value = "{id}/rev/{rid}/detail", method = RequestMethod.GET)
public String detail(@PathVariable("id") Project project, @PathVariable("rid") Rev rev, Model model, HttpSession session) {
        User user = ((User) session.getAttribute(CSession.USER));
        model.addAttribute("project", project);
        model.addAttribute("rev", rev);
        model.addAttribute("cont", revContBS.getRevCont(rev, user));

        return "template/detail";
}

The other makes an ajax call to the controller which returns JSON.

@RequestMapping(value = "file/{fid}", method = RequestMethod.GET)
public @ResponseBody String getFile(@PathVariable("fid") FV fv) {
        return repBS.getVerCon(fv);
}

Currently, I have a decoration: the header, the left menu, and the main content area. If I click the first link, it will make a full page refresh (because it makes page forwarding and jsp templating) If I click the second link, it will only change the main content area.

I want to change the behavior of the first link because it should change only the content area. Is it possible with Angular.JS + Spring MVC? I mean, I will a request a page from the spring mvc. It will template "template/detail.jsp" with given model attributes. But I will put this page into the content area of my ng-app.

Currently, I have problems in following areas:

  1. @RequestMapping(value = "{id}/rev/{rid}/detail", method = RequestMethod.GET) is parametric. I couldn't find a way to make route forwarding parametric.
  2. I don't know how I should re-serve my "template/detail.jsp" so that it will be placed into the div called ng-view.
like image 829
user706071 Avatar asked Jun 24 '13 13:06

user706071


People also ask

Can we integrate Spring MVC with angular?

4) NO it can't be said good practice to include angular build files in Spring MVC project. because every time you make changes to angular, you have to rebuild your Spring war file and deploy it again to webserver.

Does AngularJS use MVC?

The controller receives input, validates it, and then performs business operations that modify the state of the data model. AngularJS is a MVC based framework. In the coming chapters, we will see how AngularJS uses MVC methodology.

Is angular better than Spring?

"Quick to develop", "Great mvc" and "Powerful" are the key factors why developers consider AngularJS; whereas "Java", "Open source" and "Great community" are the primary reasons why Spring is favored.


1 Answers

The directive ng-view of AngularJS is used to render a template associated to the current route into your html page. The main point is that your templates should be managed client side only.

What you try to do here is to render a template server side, using Spring MVC but this is not the idea of a single page application with AngularJS.

Instead, your spring mvc controllers should only return json object : you write RESTful services and use AngularJS to render your template and fetch your model.

Here is a complete example for your use case :

index.html :

<html ng-app="myApp">
<head>
</head>
<body>
    <!-- Your menu -->
    <ul>
        <li><a href="#/project/1/rev/1">Project 1 - Rev 1</a></li>
        <li><a href="#/project/1/rev/2">Project 1 - Rev 2</a></li>
    </ul>

    <!-- Your content -->
    <div ng-view>
    </div>
</body>
</html>

Your template ("template/detail.html")

<div>Id of project : {{project.id}}</div>

Your angular application :

angular.module('myApp', []).
    config(['$routeProvider', function($routeProvider) {
        $routeProvider.
            // Bind your route with your template and associated controller
            // Your template will be loaded into ng-view area
            when('/project/:projectId/rev/:revId', { templateUrl: 'template/detail.html', controller: MyController }).

            // Default route
            otherwise({redirectTo: '/'});
    }]);

function MyController($scope, $routeParams, $http) {
    // Use $routeParams to get parameter from your current route
    var projectId = $routeParams.projectId,
        revId = $routeParams.revId;

    // Here I use $http API from AngularJS but ng-resouce may be easier to use 
    // when you have to deal with rest resources
    $http.get('project/' + projectId + 'rev/' + revId).success(function(data) {
        $scope.project = data.project;
        $scope.rev = data.rev;
    });
}

Your Spring MVC controller with your REST service :

@RequestMapping(value = "{id}/rev/{rid}/detail", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> detail(
         @PathVariable("id") Project project,
         @PathVariable("rid") Rev rev,
         HttpSession session) {

    User user = ((User) session.getAttribute(CSession.USER));

    // I use a map for the example but you should probably use a "real" object
    // The idea here is that you return a rest resource
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("project", project);
    map.put("rev", rev);
    map.put("cont", revContBS.getRevCont(rev, user));
    return map;
}

Note that if you need a more complex router, you can have a look at AngularUI project.

like image 191
Mickael Avatar answered Nov 15 '22 16:11

Mickael