Ui-router加载状态,然后我怎么运行一个函数
Ui-router loads state, then how can I run a function?
我是Angular和state的新手,对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()
。我如何运行authenticate()一旦'home'状态已加载?
另外,我能告诉angular只在这个状态下加载authenticate.js吗?或者我应该已经把它加载到模板中了。我知道,如果我在partial-home.html中包含脚本(例如<script src="authenticate.js"></script>
), chrome会抛出关于同步xmlhttprest被弃用的错误。我能不能在配置中声明authenticate。js为状态依赖之类的?
目前我已经算出来了,我可以这样做:
ivApp.controller('authenticate', function($scope) {
// start authorisation
authenticate();
});
然后在我的ui-router状态中定义控制器认证。但事情就是这样的吗?它基本上是有效的。我的身份验证函数正在做一些事情,比如改变DOM中的东西,但我读到控制器不应该用于此。
谢谢你的指点
我们来分析一下。
如果你只想在这个特定的home
状态下加载authenticate.js
,使用ocLazyLoad。这是惰性加载资源的最佳方式之一。它的工作真的很好,如果ui-路由器也是!
$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
链接在一起。
加载状态后操纵dom ?当然,这就是templateUrl
的作用!设计你的模板,使它适应你的authenticate()
函数。如果你把它和resolve
结合起来,分离关注点并没有太大的问题,因为你已经在控制器加载之前执行了authenticate()
。
编辑:添加Plnkr
您想首先惰性加载authenticate.js
,然后使用 authenticate.js
内部的函数来做一些事情。由于ui.router
中的resolve
并行执行承诺链,我们必须将它们链接起来,即首先加载您的jsfiles,然后返回您的身份验证状态。
我们需要使用$q
服务声明一个延迟承诺。然后我们在resolve中返回这个promise,这样你的控制器就会监听一个promise而不是两个promise。方法如下:
$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.
}]);
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- 我可以在json对象中添加一个函数吗
- Javascript使函数一个接一个地执行
- 是JavaScript中的函数一个对象
- 两个几乎相等的jQuery函数;一个适用于IE,一个不适用于IE
- 两个Javascript函数一个window.onload=Custom.init;和一个window.onload=f
- 使javascript加载函数一个接一个地执行
- 如何通过两个嵌套的匿名函数(一个带有超时的事件处理程序)传递变量
- 为什么我不能让两个jQuery函数一个在另一个里面呢?
- 给函数一个变量名,而不是它的值
- 如何使用嵌入函数(一个滚动页由Pete - peachananr)
- 是否有可能给JavaScript函数一个类型/类?
- 确保两个函数一个接一个地执行,其中第一个函数内部有一个异步调用
- 两个不同的ajax函数一个接一个调用返回相同的值
- jQuery第一次更改函数一个工作
- 给这个函数一个id
- 如何给回调函数一个值一个变量在特定时刻
- 使用回调使两个函数一个接一个地运行
- 两个函数(一个用php)是否可以用“;onclick”;
- 两个几乎相同的函数.一个函数用Queue进行排队.Jquery效果在queued函数上不起作用.为什么