我是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;
};
});
ContactService
app.service('ContactService', function() {
return{
'selectedPerson': null ,
'persons': [
{
"name": "Gregory Huffman",
"email": "Praesent@pedenec.net",
"birthdate": "2015-03-23T18:00:37-07:00",
"phonenumber": "07624 073918",
"address": "5880 Sed, Street",
"city": "Denderbelle",
"country": "Ethiopia"
},
{
"name": "Tad Vazquez",
"email": "dapibus.gravida@necimperdietnec.co.uk",
"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
任务中获得所有人员?
答案 0 :(得分:1)
如果您使用angular.service
来创建此服务,那么您是否应该将这些属性放在this
上?这看起来像工厂实例化,而不仅仅是服务。另一个问题与参考有关。因此,根据详细控制器何时加载,它将获得当前值selectedPerson
,但之后不会进行任何更新,因为您正在更改selectedPerson
中存储的内存位置。
例如,说这是事件的顺序:
我的建议,将您的服务更改为工厂。唯一的区别是它不是用new关键字创建的,所以返回的对象工作得很好。
angular.module('myMod').factory(/* same as service */)
我的第二个建议是避免使用$scope.$watch
或类似的东西。将父对象存储在控制器中,以便当Angular运行其摘要周期时,必须调用parent.selectedPerson
,这意味着它将查找新值,而不是直接查看$scope.selectedPerson
,而不是$scope.ContactService = ContactService;
改变一次。有意义吗?
parent.selectedPerson
在这个特定情况下哪个并不是最好的,将整个服务放在范围上,但它得到了// 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;
});
我说的替代方案是添加一个像这样的监视表达式:
{{1}}
答案 1 :(得分:0)
你可以试试这个而不是服务(app.factory ...)吗?
app.factory('ContactService', function() {
return{
'selectedPerson': null ,
'persons': [
{
"name": "Gregory Huffman",
"email": "Praesent@pedenec.net",
"birthdate": "2015-03-23T18:00:37-07:00",
"phonenumber": "07624 073918",
"address": "5880 Sed, Street",
"city": "Denderbelle",
"country": "Ethiopia"
},
{
"name": "Tad Vazquez",
"email": "dapibus.gravida@necimperdietnec.co.uk",
"birthdate": "2015-12-28T06:02:56-08:00",
"phonenumber": "(016977) 1036",
"address": "830-6354 Cubilia Rd.",
"city": "Sulzbach",
"country": "Liechtenstein"
}]
};
});
答案 2 :(得分:0)
根据您的代码,$scope.selectedPerson
中PersonDetailCtrl
变量的分配按值调用,这导致您更改ContactService
变量的原因在PersonListCtrl
中无法看到PersonDetailCtrl
中执行的内容。
使用通过引用调用在$scope.selectedPerson
中使用方法或分配PersonDetailCtrl
变量后,您的问题就会得到解决。
我创建了一个plnkr,其中我使用ContactService
中PersonDetailCtrl
的引用来参考调用。
请参阅plnkr:http://plnkr.co/edit/rQUfLBhdSsv5mf46pX1e?p=preview
// HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-example12-production</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="docsSimpleDirective">
<div ng-controller="PersonDetailController">
PersonDetailController: {{contactSvc.selectedPerson.name || 'n/a'}}
</div>
<br/>
<div ng-controller="PersonListController">
PersonListController: {{selectedPerson.name || 'n/a'}}
<br/>
<select ng-options="p.name for p in persons" ng-change="selectPerson()" ng-model="selectedPerson"></select>
</div>
</body>
</html>
// JS
(function(angular) {
'use strict';
angular.module('docsSimpleDirective', [])
.controller('PersonDetailController', function ($scope, ContactService, $rootScope){
$scope.contactSvc = ContactService;
})
.controller('PersonListController', function ($scope, ContactService, $rootScope) {
$scope.search = "";
$scope.order = "email";
$scope.persons = ContactService.persons;
$scope.selectedPerson = ContactService.selectedPerson;
$scope.selectPerson = function (person, index) {
ContactService.selectedPerson = $scope.selectedPerson;
};
$scope.sensitiveSearch = function(person) {
if ($scope.search) {
return person.name.indexOf($scope.search) == 0 ||
person.email.indexOf($scope.search) == 0;
}
return true;
};
})
.service('ContactService', function() {
return{
'selectedPerson': null ,
'persons': [
{
"name": "Gregory Huffman",
"email": "Praesent@pedenec.net",
"birthdate": "2015-03-23T18:00:37-07:00",
"phonenumber": "07624 073918",
"address": "5880 Sed, Street",
"city": "Denderbelle",
"country": "Ethiopia"
},
{
"name": "Tad Vazquez",
"email": "dapibus.gravida@necimperdietnec.co.uk",
"birthdate": "2015-12-28T06:02:56-08:00",
"phonenumber": "(016977) 1036",
"address": "830-6354 Cubilia Rd.",
"city": "Sulzbach",
"country": "Liechtenstein"
}]
};
})
})(window.angular);
我希望这能回答你的问题!!