Angular服务中self调用函数报错,$injector调用正常问题咨询
问题原因与解决方案
这个问题本质是JavaScript中this的动态绑定特性导致的,我来给你详细拆解:
为什么self.applyMusicFilter会报错?
当你在goToMedia方法里写var self = this时,self的指向完全取决于goToMedia的调用上下文:
- 如果是直接通过
artistService.goToMedia(...)调用,this确实指向你的service单例对象,这时候self能访问到applyMusicFilter; - 但如果
goToMedia被作为回调函数传递(比如绑定到DOM事件、或者作为其他异步操作的回调),this的指向会变成全局对象(非严格模式)或undefined(严格模式),这时候self自然找不到applyMusicFilter方法。
而$injector.get('artistService')是直接获取Angular维护的service单例实例,它不受调用上下文影响,所以总能访问到完整的service方法。
修复方案
解决这个问题最稳妥的方式是在factory内部预先创建一个明确的service对象引用,彻底摆脱对this的依赖。修改你的代码如下:
angular.module('my_proj').factory('artistService', function($injector, $ionicListDelegate, $rootScope, $state, $stateParams, $timeout, $translate, SomeStore, appConstants, appService, coreService, moment, loginService) { // 先定义service对象,用变量保存引用 var artistService = { goToMedia: function(artistId, state) { // 直接使用预先定义的artistService变量 SomeStore.findByPk(artistId, {}, function(reminder) { artistService.applyMusicFilter(reminder); }) }, // 这里是你的applyMusicFilter方法(假设定义在这里) applyMusicFilter: function(reminder) { // 你的业务逻辑代码 } }; return artistService; })
这个方案的优势:
- 无论
goToMedia被以何种方式调用,都能稳定引用到service单例; - 代码可读性更强,避免了
this绑定带来的歧义; - 完全兼容所有JavaScript环境,不需要依赖ES6特性。
如果你的项目已经支持ES6,也可以用箭头函数来固定上下文(箭头函数的this继承自外层作用域),比如:
goToMedia: function(artistId, state) { SomeStore.findByPk(artistId, {}, (reminder) => { // 箭头函数里的this继承自外层goToMedia的this this.applyMusicFilter(reminder); }) }
不过第一种预先保存service引用的方式,在AngularJS项目中是更通用、更安全的实践。
内容的提问来源于stack exchange,提问作者The_Unknown
相关产品推荐
相关产品推荐

