I need some help making my solution to this problem more elegant.
Summary of app
The app is a single-page app using pushstate. The landing page (path: /) contains links to articles (path: /article/:articleId). There is also a link to create an article (path: /create). When either link is clicked, the URL is changed and the content is loaded into a modal (I'm using Bootstrap but the implementation is fairly irrelevant).
Solution
So far I have (and please excuse errors as I'm coding blind):
index.htm
<!doctype html>
<html ng-app="App">
<head>
<title>{{page.title}}</title>
</head>
<body>
<section id="articles" ng-controller="HomepageCtrl">
<ul>
<li ng-repeat="article in articles">
<a href="/article/{{article.id}}">{{article.name}}</a>
</li>
</ul>
</section>
<!-- markup simplified for example -->
<modal id="modal">
<div class="content ng-view></div>
</modal>
</body>
</html>
app.js
angular.module('Application', [], ['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider.when('/article/:articleId', {
templateUrl : '/templates/article.htm',
controller : 'ArticleCtrl'
}).when('/create', {
templateUrl : '/templates/create.html',
controller : 'CreateCtrl'
});
$locationProvider.html5Mode(true);
}]).controller('HomepageCtrl', ['$scope', '$rootScope', function($scope, $rootScope) {
$rootScope.page = {
title : 'This is the homepage'
};
$scope.articles = [];
$scope.articles.push({
id : 1,
name : 'Interesting article'
});
}]).controller('ArticleCtrl', ['$scope', '$rootScope', '$routeParams', function($scope, $rootScope, $routeParams) {
$('#modal').modal();
$rootScope.page = {
title : 'This is article {{article.name}}' /* Not sure if this works! */
};
}]).controller('CreateCtrl', ['$scope', '$rootScope', function($scope, $rootScope) {
$('#modal').modal();
$rootScope.page = {
title : 'This is the article creation form'
};
}]);
Templates omitted.
Problem
While this solution works, it's not great. The homepage content remains in the background and is separated from the modal content, which is good. When the route is matched, the template content is retrieved and the controller is hit, the modal opens displaying the content (ng-view). This is also good. However, I don't think controllers should be opening modals.
What is the most elegant way of doing this? The concept of routing content into the modal with unique controllers is significant to the application: there will be lots more pages added which will all need to follow this convention. There are other caveats, e.g. browser back button and closing the modal should return user to homepage, but these are less significant right now. Once I understand where to sit this logic and how it interfaces with the controllers I'll be happy.