2016-11-12 139 views
0

访问私有变量我写了下面的工厂:AngularJS工厂 - 从方法

.factory('UserFact', function() { 
    var user = []; 
    return { 
    'setUser': function(user) { 
    this.user = user; 
     console.log('(1) User set: ' + this.user); 
     console.log('(2) User id is now: ' + this.user.uid); 
    }, 
    'updateSport': function(sportid) { 
    console.log('(3)Update sport ' + sportid + 'for user id ' + this.user.uid); 
    } 
} 

使用它通过以下方式在我的控制器:

function ($scope, $stateParams, DatabaseFact, UserFact) { 

    // variables 
    $scope.sports = []; 
    $scope.sports = DatabaseFact.getSports(); 

    // functions 
    $scope.updateSport = UserFact.updateSport; 

    // execution 
    UserFact.setUser({uid: '123456', name: 'forrest'}); 
} 

并通过列表从我的观点触发它触发按钮:

updateSport(sport.id) 

我的问题是,控制台日志打印如下:

(1) User set: [Object] Object 
(2) User id is now: 123456 
(3) Update sport 1 for user id undefined 

您是否知道为什么我的用户标识在日志3中未定义?

感谢

回答

0

我不知道你是多么熟悉JavaScript,但我怀疑你被抓出来您的两个函数调用中的this引用有所不同。

要在这两个函数中调试此尝试日志记录this到控制台。你应该注意到它们不同,这就解释了你的问题的原因。

修复可能是不使用this关键字,例如,功能setUser将成为:

'setUser': function(_user) { 
    user = _user; 
} 

你可以找到关于JS this更多信息,谷歌,尝试https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/this的一个开始。

+0

我来自C++和Java。我在JavaScript中使用范围非常困难,在JS中看起来更难以理解...... –

0

这是不确定的,因为你的函数使用this,但是从它的原始对象(用户服务)范围复制。

您可以停止使用this,而是使用user变量,您声明并初始化为空数组(为什么,顺便说一句?),但从来没有使用过其他地方,或者做

$scope.updateSport = function() { 
    UserFact.updateSport; 
} 

注你命名你的服务“UserFact”,但它不是一个实体。它不创造任何东西。它只允许设置用户并更新其运动。那不是工厂。工厂是用来创造事物的对象。这里的工厂是传递给module.factory()的函数,它用于创建和返回服务实例,最好叫做UserService

+0

我来自C++,我用它来初始化它们即将变成的类型的变量;这里的用户是一个数组。你推荐别的吗?另外,我无法找到工厂与服务之间真正区别的任何可以理解的解释吗?任何建议? –

+0

服务是控制器和其他服务使用的内容。服务是在其他服务,控制器,指令等中通过角度注入的内容。具有两个方法setUser()和updateSport()的对象是服务。传递给factory()函数的函数是工厂:它创建并返回服务。假设你调用了'UserFact.setUser({uid:'123456',name:'forrest'});',用户不是一个数组。这是一个对象。 –

1

由于其实施的原因,这对我来说很有意义。在您的控制器中,您实际上是将方法引用复制到$ scope.updateSport。所以无论何时执行方法,它都会在控制器和this - > $ scope实例的上下文中执行,但不是一个服务实例。

由于你的控制器已经有了uid,它只是返回undefined。

要解决这个问题,你需要有一个方法体updateSort并调用UserFact.updateSport

$scope.updateSport = function(){ 
    UserFact.updateSport(); 
}