tkddnjs88@gmail.com / lswswswl@naver.com 이상원
developer@applicat.co.kr
http://slides.com/lsw/ui-router/live
tkddnjs88@gmail.com lswswswl@naver.com 이상원
The de-facto solution to flexible routing
with nested views in AngularJS
*(ui-router에서는 optional)
ref : http://slides.com/timkindberg/ui-router#/
$routeProvider
.when('/shopDetail/:productId', {
templateUrl: 'shop-detail.html',
controller: 'shopDetailController'})
$stateProvider .state('shop.detail', { url: '/shopDetail/:productId', templateUrl: 'shop-detail.html', controller: 'shopDetailController'})
ref : http://slides.com/timkindberg/ui-router#/
index.html
ng-view
Content
Header
ng-include
ref : http://www.slideshare.net/alexebogdan/angular-promisesandadvancedrouting?related=1
ng-switch
ng-show
/hide
index.html
ui-view
List
Header
ui-view
ui-view
Detail
Sub Detail
동물 선택 : 고양이▼
지역 선택: 서울 ▼
[고양이 / 서울] 나비
[서울] 지역의
[고양이] 입양률
Filters
Animals
Graph
[고양이 / 서울] 길동이
[고양이 / 서울] 얼룩이
<!-- index.html -->
<body ng-app>
<div ui-view></div>
</body>
<!-- index.html -->
<body ng-app>
<div ui-view="filters"></div>
</body>
$stateProvider.state('name', {stateConfig})
nesting views
해당 state의 configuration
$stateProvider .state('main', { //template, controller}) .state('main.filters', { // ...})
$stateProvider .state('main', { //template, controller}) .state('filters'), { parent: 'main' })
<!-- main.html -->
<body ng-app>
<div ui-view></div>
</body>
<!-- filters.html -->
<div ui-view></div>
<!-- animals.html -->
<div>list content</div>
(template의 ui-view 지시자와 이름과 같아야 합니다.)
$stateProvider .state('main.filters.animals', { url: '/animals', views: { filters: { templateUrl: 'animals.html' } } })
$stateProvider .state('main', { url: '/', views: { filters: { templateUrl: 'filters.html' }, animals: { templateUrl: 'animals.html' }, graph: { templateUrl: 'graph.html' }
}
})
하나의 state가 여러개의 view를 가진 경우, view의 이름은
중복될 수 없습니다
$stateProvider .state('main', { url: '/', views: { 'filters@main': { templateUrl: 'filters.html' }, 'animals@main': { templateUrl: 'animals.html' }, 'graph@main': { templateUrl: 'graph.html' }
}
})
ex) viewName@stateName,
main.html
ui-view="filters"
filters
Header
ref : http://slides.com/timkindberg/ui-router#/11/8
ui-view = "animals"
ui-view="graph"
List
Graph
main.html
ui-view="filters"
filters
Header
ui-view = "animals"
ui-view="graph"
List
Graph
ref : http://slides.com/timkindberg/ui-router#/11/10
main.html
ui-view="filters"
filters
Header
ui-view = "dataDisplay"
List and Graph
ref : http://slides.com/timkindberg/ui-router#/11/10
filters의 조건에 list와 graph가 동일하게 영향을 받을 때,
list와 graph는 filters에 의존적/종속적입니다.
즉, list와 graph는 filters를 parent로 가질 수 있습니다.
만일 list와 graph가 seperated scope이 필요하다면, 두개의 별도의 named view가 될 필요가 있고, 아니라면 하나의 view로 표현할 수 있습니다.
결론적으로 routing을 구성하기 전,
'각 view들이 별도의 scope으로 분리가 필요한가',
'각 view들이 서로 어떻게 의존적인가' 가 핵심입니다.
url은 state의 hierarchy 에 따릅니다.
만일 부모 state에 url이 존재한다면, 자식 state의 url에 prepend 됩니다.
.state('main.mypage', {
url: '/mypage', templateUrl: 'mypage.html' }) .state('main.mypage.settings', { url: '/settings', templateUrl: 'settings.html' })
projectname/#/mypage/settings
state가 반드시 url을 포함할 필요는 없습니다.
단독적으로 view 에 보여질 필요가 없이
자식 state와 언제나 함께 activate되는 state라면,
그래서 url로 이동할 필요가 없다면 사용하지 않아도 무방합니다.
.state('main.filters', {
url: '/filters', //꼭 필요하지는 않다. templateUrl: 'mypage.html' }) .state('main.filters.table', { url: '/table', templateUrl: 'table.html' })
named param, search param 등을 url에 포함시킬 수 있습니다.
.state('main.surveyList.surveyDetail', {
url: '/surveyDetail/:surveyId', templateUrl: 'survey-detail.html' }) .state('main.mypage.settings', { url: '/settings', templateUrl: 'settings.html' })
/surveyDetail/507f1f77bcf86cd799439011
그런데 mongoDB ObjectId라고 가정하면...좀 길다?
.state('main.surveyList.surveyDetail', {
url: '/surveyDetail/:selectedDate', templateUrl: 'survey-detail.html' })
/surveyDetail/Sat Nov 28 2015 00:00:00 GMT+0900 (KST)
.state('main.surveyList.surveyDetail', {
params: { selectedDate: '' }, url: '/surveyDetail', templateUrl: 'survey-detail.html' })
ref : http://www.slideshare.net/nirkaufman/angular-js-routing-options
state
Requested
$stateChangeStart
$stateChangeError
$stateNotFound
$stateChangeSuccess
ui-view
kicks-in
$viewContentLoaded
onload function
all done!
$state.go() 를 사용해
여러가지 필요한 연산 후에 이동 가능
<ul>
<li ng-repeat="item in animalList"
ui-sref="animal.detail({animalId: item.id})">상세보기
</li>
<ul>
<ul>
<li ng-repeat="item in animalList"
ui-sref="animal.detail({animalId: item.id})"
href="#/animalDetail/1357">상세보기
</li>
<ul>
url="/animalDetail/:animalId"
<ul>
<li ng-repeat="item in animalList"
ng-click="vm.getAnimalDetail({item.id})">
상세보기</li>
<ul>
function getAnimalDetail(itemId) {
animalService.getAnimals({id:itemId}).$promise
.then(function(result){
//필요한 작업 수행
//필요한 작업 수행
$state.go('animal.detail',{animalId: result.id})
})
.catch(function(error){
})
}
ex) controller(vm)에서 필요한 작업을 수행 후 $state.go()로 이동
<a class="item active">
/home
클라이언트 혹은 디자이너의 요구사항으로
좀 복잡한 커스텀 탭이라던지 내브바라던지 컴포넌트를 만들어야 할 때...
아니면 간단한거라도 좀 더 편하게 하고 싶을 때...
<nav> <ul> <li ui-sref-active="custom-active" ui-sref="place.office">오피스</li> <li ui-sref-active="custom-active" ui-sref="place.house">주택</li> <li ui-sref-active="custom-active" ui-sref="place.apartment">아파트</li> </ul> </nav>
ui-sref-active="class1 class2 class3"
얼마든지 여러개의 클래스를 간단히 적용할 수 있습니다.
ref : http://www.slideshare.net/nirkaufman/angular-js-routing-options
state
Requested
$stateChangeStart
$stateChangeError
$stateNotFound
$stateChangeSuccess
ui-view
kicks-in
$viewContentLoaded
onload function
all done!
.state('main.board.writePost', {
url: '/writePost', templateUrl: '/writePost.html', authenticate: true })
.state('main.mypage', {
url: '/mypage', templateUrl: '/mypage.html', authenticate: true })
angular.module('appName', [module1, module2..]) .run(['$rootScope', '$state', 'myAuth', function($rootScope, $state, myAuth) {
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams) {
if(toState.authenticate && !myAuth) {
event.preventDefault();
$state.go('login');
}
})
}
])
$rootScope가 아니라 별도의 모달서비스를 주입해서 사용할 수도 있습니다.
angular.module('appName', [module1, module2..]) .run(['$rootScope', '$state', 'myAuth', function($rootScope, $state, myAuth) {
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams) {
if(toState.authenticate && !myAuth) {
event.preventDefault();
$rootScope.loginModal.show();
}
})
}
])
그래서 +a를 준비했습니다.
이것도 알고계실 분들에게는 미리 심심한 사과의 말씀을...
+a같은 녀석