如何正确绑定到 AngularJS 中的服务 属性?
How to bind properly to a service property in AngularJS?
我有一个工厂,那里有几个预定义的合作伙伴(也可以是其他任何东西,我认为这是一个易于理解的示例)。在 运行 时间,我们 select 当前合作伙伴(基于我在此省略的一些逻辑)。
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
});
我找到了一些解决方法(在我看来...它们是解决方法吗?),但对我来说感觉不自然,所以我想请问有没有更好的办法
在 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,
//...
};
});
我认为您没有遗漏任何明显的东西。您的两种解决方法对我来说似乎都可以,除了在后一种情况下我可能会使用以下结构:
var partners = { ... };
var initPartner = function () {
retObj.partner = partners.secondPartner;
};
var retObj = {
initPartner: initPartner,
partners: partners,
partner: partners.firstPartner
};
return retObj;
更改为:
this.partner = partners.secondPartner;
在您的 initPartner 方法中。这样就解决了。
当你做的时候你真正在做什么
var partners = { ... }
var partner = partners.firstPartner;
是,您在 class 中创建本地对象,但它们不是 class 的公开成员。并与
return {
initPartner: initPartner,
partners: partners,
partner: partner
};
您创建 class 的成员,并将局部变量的值复制到 class 的成员。在您的 initPartner 方法中,您更改了本地对象,但 class' 对象保持不变。
我会采用使用 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;
}
}
})();
请注意,剩下的唯一 public/accessible 个成员是 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"
我有一个工厂,那里有几个预定义的合作伙伴(也可以是其他任何东西,我认为这是一个易于理解的示例)。在 运行 时间,我们 select 当前合作伙伴(基于我在此省略的一些逻辑)。
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
});
我找到了一些解决方法(在我看来...它们是解决方法吗?),但对我来说感觉不自然,所以我想请问有没有更好的办法
在 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,
//...
};
});
我认为您没有遗漏任何明显的东西。您的两种解决方法对我来说似乎都可以,除了在后一种情况下我可能会使用以下结构:
var partners = { ... };
var initPartner = function () {
retObj.partner = partners.secondPartner;
};
var retObj = {
initPartner: initPartner,
partners: partners,
partner: partners.firstPartner
};
return retObj;
更改为:
this.partner = partners.secondPartner;
在您的 initPartner 方法中。这样就解决了。
当你做的时候你真正在做什么
var partners = { ... }
var partner = partners.firstPartner;
是,您在 class 中创建本地对象,但它们不是 class 的公开成员。并与
return {
initPartner: initPartner,
partners: partners,
partner: partner
};
您创建 class 的成员,并将局部变量的值复制到 class 的成员。在您的 initPartner 方法中,您更改了本地对象,但 class' 对象保持不变。
我会采用使用 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;
}
}
})();
请注意,剩下的唯一 public/accessible 个成员是 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"