无法在AngularJS中获取服务中的共享数据

时间:2016-03-16 03:20:58

标签: javascript angularjs

我是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。我知道,我们可以通过点符号得到它,但我想知道,为什么这不起作用?

是否因为原型继承,每个控制器都创建了自己的新personsselectedPerson属性。如果是这种情况,那么为什么我会从ContactService.person任务中获得所有人员?

代码示例:https://jsfiddle.net/y9bLxdua/

3 个答案:

答案 0 :(得分:1)

如果您使用angular.service来创建此服务,那么您是否应该将这些属性放在this上?这看起来像工厂实例化,而不仅仅是服务。另一个问题与参考有关。因此,根据详细控制器何时加载,它将获得当前值selectedPerson,但之后不会进行任何更新,因为您正在更改selectedPerson中存储的内存位置。

例如,说这是事件的顺序:

  1. 已加载PersonListController
  2. $ scope items set ...
  3. 已加载PersonDetailController
  4. $ scope items set ... $ scope.selectedPerson = null
  5. PersonListController将selectedPerson更改为' abc'
  6. PersonDetailController未收到更新且仍为null
  7. 我的建议,将您的服务更改为工厂。唯一的区别是它不是用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.selectedPersonPersonDetailCtrl变量的分配按值调用,这导致您更改ContactService变量的原因在PersonListCtrl中无法看到PersonDetailCtrl中执行的内容。

使用通过引用调用$scope.selectedPerson中使用方法或分配PersonDetailCtrl变量后,您的问题就会得到解决。

我创建了一个plnkr,其中我使用ContactServicePersonDetailCtrl的引用来参考调用。

请参阅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);

我希望这能回答你的问题!!