[英]How to decorate current state resolve function in UI-Router? Current function isn't invoked
我試圖在$stateProvider
干,並阻止在每個解析中添加相同的auth
函數。 我已經創建了裝飾器,在每個狀態更改都會將此函數添加到當前狀態,但是不調用auth
函數,如何修復它或如何解決已討論的問題?
app.config(function ($stateProvider, $urlRouterProvider, $provide) {
$provide.decorator('$state', function($delegate, $rootScope) {
$rootScope.$on('$stateChangeStart', function(event, state, params) {
if ($delegate.current === "login" || $delegate.current === "register") {
return;
}
console.log("decorator", $delegate);
$delegate.current.resolve = {
auth: ['AuthService', '$stateParams', function(AuthService, $stateParams) {
//how to invoke this function?
if (AuthService.isAuthenticated()) {
return AuthService.me(); //promise
} else {
return false;
}
}]
};
});
return $delegate;
});
州定義:
$stateProvider.state('root', {
abstract: true,
url: '/',
views: {
"": {
controller: 'RootCtrl',
templateUrl: 'views/root.html'
},
"header@root": {
templateUrl: 'views/header.html'
}
}
})
.state('root.home', {
url: urlPrefix,
views: {
"content@artworks": {
templateUrl: 'views/home.html',
//resolve: {
// auth: ['AuthService', '$stateParams', function(AuthService, $stateParams) {
// }]
//}
}
}
})
...
如果我正確理解您的要求,我們可以使用本機UI-Router
內置decorator
:
decorator(name, func)
允許您擴展(小心)或覆蓋(由您自己承擔)$ stateProvider內部使用的stateBuilder對象。 這可用於向ui-router添加自定義功能,例如根據州名稱推斷templateUrl ... ( 在doc中閱讀更多內容 )
所以,我們可以有這個var auth
var auth = ['AuthService', '$stateParams',
function(AuthService, $stateParams) {
//how to invoke this function on needed states?
if (AuthService.isAuthenticated()) {
return AuthService.me();
} else {
return false;
}
}
];
在這里我們只使用裝飾器和一些“IF”邏輯
.config(['$stateProvider',
function($stateProvider) {
$stateProvider.decorator('views', function(state, parent) {
var result = {},
views = parent(state);
// some naive example when to not inject resolve
if (state.name === "home") {
return views;
}
// child already has that in parent
if (state.name.indexOf(".") > 0) {
return views;
}
angular.forEach(views, function(config, name) {
// here inject the resolve (if not existing)
config.resolve = config.resolve || {};
// and extend it with the auth stuff above
config.resolve.auth = auth;
result[name] = config;
});
return result;
});
}
])
后來很少有我們的州,這將由上述東西擴展
$stateProvider
.state('home', {
url: "/home",
templateUrl: 'tpl.html',
})
.state('parent', {
url: "/parent",
templateUrl: 'tpl.html',
controller: 'SharedCtrl',
})
.state('parent.child', {
url: "/child",
templateUrl: 'tpl.html',
controller: 'SharedCtrl',
});
在這里檢查它
我意識到$delegate.current
對象只包含原始的stateProvider配置數據。 要包裝解析函數,我將我的函數添加到$delegate.$current
對每個狀態的更改。
$provide.decorator('$state', function($delegate, $rootScope) {
$rootScope.$on('$stateChangeStart', function(event, state, params) {
if ($delegate.current === "err404" || $delegate.current === "login" || $delegate.current === "register") {
return;
}
console.log("decorator", $delegate);
$delegate.$current.resolve["auth"] = ['AuthService', '$stateParams', function(AuthService, $stateParams) {
if (AuthService.isAuthenticated()) {
console.log('AuthService.me()');
return AuthService.me();
} else {
return false;
}
}]
});
return $delegate;
});
更新
我在github上找到了相關的討論,你可以在toState
param中添加通用解析函數:
app.run(['$rootScope', '$state',
function($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function(event, toState) {
if (toState.name === "login" || toState.name === "register") {
return;
}
toState["resolve"]["auth"] = ['AuthService', '$stateParams', function(AuthService, $stateParams) {
if (AuthService.isAuthenticated()) {
return AuthService.me();
} else {
return false;
}
}];
});
}
]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.