Как разбить приложение AngularJS на более мелкие модули и правильно обработать маршрутизацию?
Каким будет лучший способ разделить приложение AngularJS на более мелкие куски/модуль?. Например, если у меня есть сообщение в блоге и комментарии для этого, я думаю, что я мог бы разбить его на модули, например "сообщения" и "комментарии" (?) (может быть, не лучший пример, но идея состоит в том, чтобы разделить логику приложения на отдельные модули, а не на создание огромного одномодульного приложения).
Я попытался загрузить оба модуля в отдельные узлы DOM и использовать маршрутизацию в обоих модулях соответственно. Есть несколько проблем:
- Как одностраничное приложение, я загружаю модуль комментариев, который будет использоваться даже на первой странице, даже если он не используется там.
- Так как я не могу использовать несколько ng-views внутри ng-app, я вынужден написать все обертки для своих модулей в представлении index.html и загрузить их? Должно быть так? Кажется, что это неправильно. Как/где я должен их загрузить?
- Есть ли подсказки для маршрутизации? Должен ли я распространять их в модулях или я должен объединить их все вместе? (создание одного модуля "blog" для включения модулей "posts" и "comments" в зависимости от зависимостей, все равно будет сложно определить, например, маршрутизацию "/post/: id"??)
index.html
<div class="post"><ng-view></ng-view></div>
<div class="comments"><ng-view></ng-view></div>
javascript.js
angular.module('posts', []).config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
'template': 'Showing all the posts',
'controller': 'postCtrl
})
.when('/post/:id', {
'template': 'Showing post :id',
'controller': 'postCtrl
});
}]);
angular.module('comments', []).config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/post/:id', {
'template': 'Showing post :id comments',
'controller': 'CommentsCtrl'
});
}]);
angular.bootstrap($('.post'), ['posts']);
angular.bootstrap($('.comments'), ['comments']);
Ответы
Ответ 1
Я бы разделил приложение на "модули просмотра" и на эти вспомогательные модули.
Затем я использую $routeProvider для переключения между представлениями. Я определяю различные конфигурации маршрутизации в каждом модуле.
Если мне нужны дополнительные подмодули, я загружаю их с помощью ng-include.
/* App Module */
angular.module('MyApp', ['MyApp.home', 'MyApp.blog'])
.config( function myAppConfig ( $routeProvider ) {
'use strict';
$routeProvider.otherwise({ redirectTo: '/home' });
});
/* home Module */
angular.module('MyApp.home', [])
.config(['$routeProvider', function config( $routeProvider ) {
$routeProvider.when('/home', {
controller: 'HomeController',
template: '<p>This is my Home</p>'
});
}]);
Я создал небольшой репозиторий на github, чтобы объяснить это.
Ответ 2
Вы можете определить маршруты в подмодулях:
angular.module('app', ['ngRoute', 'app.moduleX'])
.config(function($routeProvider, $locationProvider) {
$routeProvider.when('/home', {
templateUrl: 'partials/home.html',
controller: 'HomeCtrl'
});
//Handle all exceptions
$routeProvider.otherwise({
redirectTo: '/home'
});
})
angular.module('app.moduleX', []).config(function($routeProvider) {
$routeProvider.when('/settings', {
templateUrl: 'partials/settings.html',
controller: 'SettingsCtrl'
});
})
Я также написал сообщение в блоге об этой теме.
Ответ 3
Мы делаем что-то подобное с приложением портала и суб-приложениями. Несколько вещей, которые мы обнаружили:
- Только одно "приложение" может иметь маршруты и routeParams. Из-за этого, если "суб-приложение" нуждается в доступе к $routeParams, вам нужно либо перейти в "старую школу" для разбора URL-адресов, либо использовать службу событий.
- Говоря о событиях, для приложений не существует службы Angular, поэтому вам нужно будет перевернуть свою собственную службу событий, разговаривая с корневой областью для обоих приложений, и вставлять ее в оба приложения.
- Я не вижу, где мы использовали ng-view для "sub-app". Очевидно, что самонастройка непосредственно к элементу работает аналогично.
-
Поскольку только одно приложение может иметь маршруты, приложения должны быть загружены по порядку. Так что-то вроде этого:
$( function () {
$.when(angular.bootstrap($('.post'), ['posts'])).done( function() {
console.log('POSTS: bootstrapped');
//Manually add the controller to the comments element. (May or may not be
//necessary, but we were doing something that required it to work.)
$('.comments').attr('ng-controller', 'CommentsCtrl');
$.when(angular.bootstrap($('.comments'), ['comments'])).done( function() {
console.log('COMMENTS: bootstrapped');
});
});
});
Ответ 4
Надеюсь, вы можете использовать модуль маршрутизации "ui-router" .
Вот хороший учебник для этого http://www.ng-newsletter.com/posts/angular-ui-router.html