我有一个工厂,我有几个预定义的合作伙伴(可能是其他任何东西,我认为这是一个容易理解的例子)。在运行时,我们选择当前的伙伴(基于我在此省略的一些逻辑)。
angular.module('myApp').factory('PartnersService', function ($location, $log) {
var partners = {
firstPartner: {
name: 'Default Partner',
id: 1 // just an extra property as example
},
secondPartner: {
name: 'Other Partner',
id: 2
}
};
// set default value
var partner = partners.firstPartner;
var initPartner = function () {
// based on some logic (omitted), select partner
partner = partners.secondPartner;
$log.log("initPartner should have changed partner to " + partner.name);
};
return {
initPartner: initPartner,
partners: partners,
partner: partner,
};
});
然后,我想以PartnersService.partner
的身份访问该合作伙伴并查看其更改,例如来自控制器:
angular.module('myApp').controller('myController',
function ($scope, $log, PartnersService) {
// PartnersService.partner is the default partner (firstPartner)
PartnersService.initPartner();
// After initPartner, PartnersService.partner is still
// the default, but I expected it to change
});
我找到了一些解决方法(在我看来...... 是他们的解决方法吗?),但对我来说感觉不自然,所以我想问一下是否有&#39 ;更好的方式。
在JS Bin上查看我的完整工作示例。如果你觉得这个例子有点冗长,我很抱歉,但我想确保Stack Overflow用户理解我的担忧,并指出我的想法是否有问题。
解决方法1(getter?):
angular.module('myApp').controller('myController', function ($scope, $log, PartnersService) {
PartnersService.initPartner();
var partner = PartnersService.getPartner();
$log.log('I could use a getter: ' + partner.name);
});
angular.module('myApp').factory('PartnersService', function ($location, $log) {
var getPartner = function () {
return partner;
};
return {
getPartner: getPartner,
// ...
};
});
解决方法2(嵌套在对象文字中):
angular.module('myApp').controller('myController', function ($scope, $log, PartnersService) {
PartnersService.initPartner();
$log.log('or nest the partner in an extra object literal: '
+ PartnersService.extraObjectLiteral.partner.name);
});
angular.module('myApp').factory('PartnersService', function ($location, $log) {
var partners = { /*...*/ }
var extraObjectLiteral = {
partner: partners.firstPartner
};
var initPartner = function () {
// based on some logic (omitted), select partner
extraObjectLiteral.partner = partners.secondPartner;
};
return {
extraObjectLiteral: extraObjectLiteral,
//...
};
});
答案 0 :(得分:1)
更改为:
this.partner = partners.secondPartner;
在initPartner方法中。这将解决它。
当你做
时你真正在做什么 var partners = { ... }
var partner = partners.firstPartner;
是,您在类中创建本地对象,但它们不是该类的公开成员。
return {
initPartner: initPartner,
partners: partners,
partner: partner
};
创建类的成员,并将局部变量的值复制到类的成员。在initPartner方法中,您更改了本地对象,但类的对象保持不变。
答案 1 :(得分:1)
我会选择使用getter和setter的方法,因为它遵循Revealing Module Pattern,这是维护更清晰,更易读和易懂的代码的首选。
工厂代码如下。
(function () {
angular.module('myApp').
factory('PartnersService', PartnersService);
function PartnersService($location, $log) {
var partners = {
firstPartner: {
name: 'Default Partner',
id: 1 // just an extra property as example
},
secondPartner: {
name: 'Other Partner',
id: 2
}
};
var partner;
//Set default value
setDefaultPartner();
var service = {
getPartner: getPartner,
setPartner: setPartner
};
return service;
/*** Function Declarations ***/
/* Accessible Functions */
function getPartner() {
return partner;
}
function setPartner() {
var selectedPartner = initPartner();
return selectedPartner;
}
/* Private Functions */
function initPartner() {
/*
* Some (omitted) logic to select partner
*/
partner = partners.secondPartner;
$log.log("initPartner should have changed partner to " + partner.name);
return partner;
}
function setDefaultPartner() {
partner = partners.firstPartner;
}
}
})();
请注意,唯一公开/可访问的成员是getPartner
和setPartner
(调用initPartner
)函数。
控制器如下。
(function () {
angular.module('myApp').
controller('myController', myController);
function myController($scope, $log, PartnersService) {
$scope.partner = PartnersService.getPartner();
$log.log("should be default partner: " + $scope.partner.name);
$scope.partner = PartnersService.setPartner();
$log.log("After setPartner which calls initPartner, the current partner is now the " + $scope.partner.name);
}
})();
修改JS Bin,以下是生成的控制台日志。
"should be default partner: Default Partner"
"initPartner should have changed partner to Other Partner"
"After setPartner which calls initPartner, the current partner is now the Other Partner"
答案 2 :(得分:0)
我认为你没有遗漏任何明显的东西。你的两个解决方案似乎都没问题,除了在后一种情况下我可能会使用以下结构:
var partners = { ... };
var initPartner = function () {
retObj.partner = partners.secondPartner;
};
var retObj = {
initPartner: initPartner,
partners: partners,
partner: partners.firstPartner
};
return retObj;