[英]How can I route to different URLS in angularjs UI-Router for items in ng-repeat, Need to modify state in ui-router
[英]Ui-router loads state, then how can I run a function?
我是Angular的新手,並指出我的頭圍繞着ui-router。 我用jQuery做了太久了。 在jQuery中,我可以用ajax加載一些東西,然后在成功時加載,也許運行另一個函數。 你是怎么用Angular做的?
例如,我有以下內容
var ivApp = angular.module('ivApp', ['ui.router']);
ivApp.config(function($urlRouterProvider, $stateProvider){
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'partials/partial-home.html'
})
});
這只是將partial-home.html
加載到我的ui-view
。 但是一旦完成,如何告訴它運行一個函數? 例如,我有authenticate.js
和一個函數authenticate()
。 一旦'home'狀態加載,我如何運行authenticate()?
另外,我可以告訴angular只為這個狀態加載authenticate.js嗎? 或者我應該已經將其加載到模板中。 我知道如果我將該腳本包含在partial-home.html中(例如<script src="authenticate.js"></script>
),chrome會拋出一個關於同步xmlhttprest被棄用的錯誤。 所以somhow在配置中,我可以聲明authenticat.js作為狀態的依賴或類似的東西嗎?
在我鍛煉的那一刻,我可以做類似的事情:
ivApp.controller('authenticate', function($scope) {
// start authorisation
authenticate();
});
然后定義控制器在我的ui-router狀態中進行身份驗證。 但它是如何完成的? 它基本上有效。 我的身份驗證功能正在做更改DOM中的事情,但我不應該使用控制器。
謝謝你的任何指示
讓我們分解成幾部分。
如果您只想在此特定的home
狀態下加載authenticate.js
,請使用ocLazyLoad 。 這是懶惰加載資源的最佳方式之一。 如果ui-router也很好用!
$stateProvider.state('index', {
url: "/", // root route
views: {
"lazyLoadView": {
controller: 'AppCtrl', // This view will use AppCtrl loaded below in the resolve
templateUrl: 'partial-home.html'
}
},
resolve: { // Any property in resolve should return a promise and is executed before the view is loaded
loadMyCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
// you can lazy load files for an existing module
return $ocLazyLoad.load('js/authenticate.js');
}]
}
});
如果要在加載狀態后運行authenticate()
,則可以通過多種方式執行此操作。 當然,一種方法是監聽$stateChangeSuccess
事件,但我會避免使用它,因為你知道,全局變量和全局變量都很糟糕。 我不想因為我有一個非常具體的用例而污染我的$rootScope
。
您也可以在ui-router中使用resolve
。 在加載狀態之后和實例化控制器之前執行Resolve
。 我建議使用這種方法,因為你可以將你的承諾與ocLazyLoad
一起ocLazyLoad
,如果你正在使用它(你應該)。
在加載狀態后操縱DOM? 當然,這就是templateUrl
用途! 設計您的模板,使其符合您的authenticate()
函數。 如果將它與resolve
結合使用,那么分離關注點並沒有太多問題,因為在加載控制器之前已經執行了authenticate()
。
編輯:在Plnkr中添加
你想先懶洋洋地加載authenticate.js
,然后用函數內部 authenticate.js
做一些事情。 既然resolve
在ui.router
並行執行承諾鏈,我們必須把它們連起來,即先加載jsfiles,然后回到您的身份驗證的狀態。
我們需要使用$q
服務聲明延遲的承諾。 然后我們在決心中返回此承諾,以便您的控制器正在聽一個承諾而不是兩個承諾。 方法如下:
$stateProvider
.state('Home', {
templateUrl: 'home.html',
controller: 'homeCtrl',
resolve: {
//need to chain our promises since we neeed to first load the authenticate.js
//and second, execute authenticate()
loadJsAndAuth: ['$ocLazyLoad', '$q', '$injector', function($ocLazyLoad, $q, $injector) {
//declare a deferred promise
var deferred = $q.defer();
//now load the authenticate.js
$ocLazyLoad.load('authenticate.js').then(
//load successful! proceed to use our authenticate function!
function(success) {
//since we already have loaded authenticatejs, now we can inject the service and use it
var authSvc = $injector.get('authenticateSvc');
//this is just a demo on how to authenticate.
//change this to banana to see the authenticate fail
var fruits = 'apple'
if (authSvc.authenticate(fruits)) {
//authenticate pass, resolve the promise!
deferred.resolve('authenticated!');
}
//authenticate fail, reject the promise
deferred.reject('authenticate failed');
},
//load of jsfiles failed! reject the promise.
function(error) {
deferred.reject('Cannot load authenticate.js')
})
return deferred.promise;
}]
}
})
在您的控制器中,您可以獲得已解決的承諾!
//you can get access to what is is being resolved by loadJsAndAuth
.controller('homeCtrl', ['$scope', 'loadJsAndAuth', function($scope, loadJsAndAuth) {
$scope.status = loadJsAndAuth // this is resolved promises.
}]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.