2016-03-16 31 views
0

我是AngularJS的新手,并且出现了一个奇怪的情况,我无法在两个控制器PersonDetailCtrl和PersonListCtrl和服务ContactService之间共享数据。下面是用于PersonDetailCtrl无法在AngularJS中获取服务中的共享数据

对于每个分量的码上述

代码

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": "[email protected]et", 
      "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" 
     }] 
}; 
}); 

任何人都可以解释我,为什么我没有得到在PersonDetailCtrlselectedPerson。我知道,我们可以通过点符号来获得它,但我想知道,为什么这不起作用?

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

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

+1

请把完整的服务。想看看它。 – Gary

+0

重构服务 –

回答

1

如果使用angular.service创建这个服务,你不应该把这些属性上this?这看起来像一个Factory实例化,然后是一个Service。另一个问题与参考文献有关。因此,取决于Detail控制器何时加载,它将获得当前值selectedPerson,但之后没有任何更新,因为您正在更改存储在selectedPerson中的内存位置。

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

  1. PersonListController加载
  2. $范围的项目设置...
  3. PersonDetailController加载
  4. $范围的项目进行设置。 .. $ scope.selectedPerson = null
  5. PersonListController将selectedPerson更改为'abc'
  6. PersonDetailController不会收到更新,仍然为空

我的建议,将您的服务更改为工厂。唯一的区别是它不是用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; 
}); 
+0

你能解释为什么它不会得到更新吗?它是一种双向数据绑定? –

+1

当您的PersonDetailController加载时,它立即和一次只将$ scope.selectedPerson设置为存储在ContactService.selectedPerson中的任何值。除非控制器被重新创建,否则它不会再这样做。因此,当PersonListController更改ContactService.selectedPerson时,它实际上会更改ContactService.selectedPerson指向的内存地址。虽然PersonDetailController仍在查看旧的内存地址 – Spidy

+2

这是一个关于什么是和什么不是双向数据绑定的非常常见的误解。或者至少如何在内存中存储和引用JavaScript变量 – Spidy

0

你可以试试这个而不是服务(app.factory ...)吗?

app.factory('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" 
     }] 
}; 
}); 
+0

@UditPanchal让我知道如果两个绑定没有发生 – Gary

+0

其不工作:( –

+0

你可以把一个简单的plunkr或jsfiddle。将纠正问题区域 – Gary

0

根据你的代码,分配给$scope.selectedPerson变量PersonDetailCtrl通话按值这是导致你在PersonListCtrl执行ContactService变量的变化不是PersonDetailCtrl可见的原因。

一旦你使用的方法或使用分配调用参照PersonDetailCtrl$scope.selectedPerson变量,您的问题将得到解决。

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

请参考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": "[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" 
     }] 
}; 
}) 


})(window.angular); 

我希望这回答您的查询!