我是AngularJS的新手,遇到了一种奇怪的情况,我无法在我的两个控制器PersonDetailCtrl和PersonListCtrl以及服务ContactService之间共享数据。以下是上述每个组件的代码
PersonDetailCtrl的代码
app.controller('PersonDetailController', function ($scope, ContactService, $rootScope){
$scope.selectedPerson = ContactService.selectedPerson;
}
PersonListCtrl的代码
app.controller('PersonListController', function ($scope, ContactService, $rootScope) {
$scope.search = "";
$scope.order = "email";
$scope.persons = ContactService.persons;
$scope.selectedPerson = ContactService.selectedPerson;
$scope.selectPerson = function (person, index) {
$scope.selectedPerson = person;
ContactService.selectedPerson = person;
};
$scope.sensitiveSearch = function(person) {
if ($scope.search) {
return person.name.indexOf($scope.search) == 0 ||
person.email.indexOf($scope.search) == 0;
}
return true;
};
});
联系服务
app.service('ContactService', function() {
return{
'selectedPerson': null ,
'persons': [
{
"name": "Gregory Huffman",
"email": "[email protected]",
"birthdate": "2015-03-23T18:00:37-07:00",
"phonenumber": "07624 073918",
"address": "5880 Sed, Street",
"city": "Denderbelle",
"country": "Ethiopia"
},
{
"name": "Tad Vazquez",
"email": "[email protected]",
"birthdate": "2015-12-28T06:02:56-08:00",
"phonenumber": "(016977) 1036",
"address": "830-6354 Cubilia Rd.",
"city": "Sulzbach",
"country": "Liechtenstein"
}]
};
});
谁能解释我,为什么我没有在
selectedPerson
中得到PersonDetailCtrl
。我知道,我们可以通过点表示法来获取它,但是我想知道,为什么这不起作用?是否由于原型继承而使每个控制器都具有自己的新
persons
和selectedPerson
属性。如果是这样,那么为什么我要从ContactService.person
任务中得到所有人员?代码示例:https://jsfiddle.net/y9bLxdua/
最佳答案
如果使用angular.service
创建此服务,是否不应该将这些属性放在this
上?这看起来像是工厂实例而不是服务。另一个问题与参考有关。因此,根据详细信息控制器加载的时间,它将获取selectedPerson
的当前值,但此后将不获取任何更新,因为您正在更改selectedPerson
中存储的存储位置。
例如,说这是事件的顺序:
PersonListController已加载
已设置$ scope项...
PersonDetailController已加载
$ scope项已设置... $ scope.selectedPerson = null
PersonListController将selectedPerson更改为“ abc”
PersonDetailController没有收到更新,但仍然为null
我的建议是,将您的服务更改为工厂。唯一的区别是它不是使用new关键字创建的,因此您返回的对象可以正常工作。
angular.module('myMod').factory(/* same as service */)
我的第二个建议是避免使用
$scope.$watch
或类似的东西。将父对象存储在控制器中,以便当Angular运行其摘要循环时必须调用parent.selectedPerson
,这意味着它将查找新值,而不是直接查看$scope.selectedPerson
,该值一旦设置就不会更改。合理?$scope.ContactService = ContactService;
在这种特定情况下,这不是最大的解决方案,将完整的服务放在范围内,但可以为
parent.selectedPerson
我说过的替代方法是添加一个watch表达式,如下所示:
// This is an extreme shorthand to achieve what you need
// It runs each time the digest cycle does, updating your $scope.selectedPerson
$scope.$watch(function() {
return $scope.selectedPerson = ContactService.selectedPerson;
});