两个控制器之间的服务无法正常工作

问题描述:

我使用AngularJS显示员工记录。我正在使用两个视图来显示数据,我正在使用两个视图emp-box.htm及其相应的控制器(empController),并在此控制器中employeeBoxController我正在从服务中获取数据,我想要在中获取的结果用于empController并显示鉴于(emp-list.htm),我创建了一个服务eService两个控制器之间的服务无法正常工作

app.service('dataService',function() { 

    var s = {}; 

    this.setData = function(data,key) { 
    s[key]=data; 
    }, 
    this.getData = function(key) { 
    return s[key]; 
    } 
    this.hello = function() { 
    return 'hello'; 
    } 
}) 

用于提取结果,并在employeeBoxController设定数据和empController越来越但是当我取的empController使用console.log(dataService.getData('result'));数据我得到undefined

employeeBoxController

app.controller("employeeBoxController", ['$scope', 'employeeService', 
    'dataService', function($scope, employeeService, dataService) { 
    $scope.getEmployeeDetails = function(eid) { 
    $scope.isLoading = false; 
    employeeService.getDetails($scope.eid).then(function(result) { 
     dataService.setData(result, 'result'); 
     $scope.isLoading = true; 
     console.log(dataService.getData('result')); 
    }) 
    } 
}]) 

empController是: -

app.controller("empController", ['$scope', 'employeeService', 'dataService', 
    function($scope, employeeService, dataService) { 

    $scope.result = dataService.getData('result'); 
    //console.log(dataService.hello()); 

    console.log(dataService.getData('result')); 

    console.log(dataService.hello()); 
    } 
]) 

服务类employeeService是: -

app.config(["employeeServiceProvider",function(employeeServiceProvider){ 
     employeeServiceProvider.config('http://localhost:8080/pos'); 
    }]); 

    app.provider("employeeService",function(){ 
    var myurl=''; 

    this.config=function(eurl){ 
     myurl=eurl; 
    } 

    this.$get=['$http','$log',function($http,$log){ 
     var employeeobj={}; 
     employeeobj.getDetails=function(eid){ 
     return $http.get(myurl+'/getEmployees/'+eid); 
    } 

    return employeeobj; 
    }]; 
    }); 

emp-box.htm是: -

<div> 
    Enter the id: <input type="text" ng-model="eid"/> 
    <button ng-click="getEmployeeDetails()">show</button> 
    </div> 
    emp-list.htm is:- 
     <div class="panel panel-primary"> 
     <div class="panel-body" style="text-align:center; margin:0 auto"> 
     <h3>Employee Data</h3> 
     </div> 
    </div> 
     <div class="panel panel-primary"> 
     <div class="panel-body"> 
     <!-- <div ng-show="!isLoading" style="color:red"> 
     <span class="glyphicon glyphicon-time"></span>Loading... 
     </div>--> 
    <table class="table table-hover"> 
    <thead> 
     <tr> 
     <th>ID</th> 
     <th>Name</th> 
     <th>empno</th> 
     <th>salary</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr ng-repeat="oemp in result.data"> 

     <td>{{oemp.eid}}</td> 
     <td>{{oemp.name}}</td> 
     <td>{{oemp.empno}}</td> 
     <td>{{oemp.sal}}</td> 
    </tr> 
    </tbody> 

    </table> 
    </div> 
    </div> 
+0

setData是否返回一些东西? – DevMoutarde

+0

no setData正在设置数据,它不会返回任何东西 – shashank

+0

但是不包含任何数据?只是想图 – DevMoutarde

从我所了解的你试图缓存你的API结果到另一个服务,所以你不必在另一个控制器再次调用API。此外,empController首先被执行,并且当您在做dataService.getData('result')时,设置它的API响应还没有被接收,然后又被另一个服务调用。我建议你将这两个服务结合起来,这样就可以缓存API调用本身,而不是缓存服务中的确切值,并且在缓存不包含数据的情况下,调用API并缓存它。

这是我会做的东西,说CacheAPIService

app.factory('CacheAPIService', ['$http', function($http) { 
    var cache = {}; 
    return { 
    get: function(api) { 
    if(angular.isUndefined(cache[api])) { 
     cache[api] = $http.get(api); //storing in cache while making API call 
    } 
    return cache[api]; //Return from cache 
    }, 
    clear: function(api) { 
     delete cache[api]; 
    } 
    } 
}]); 

所以,每当你需要做一个缓存API调用,除了使API调用它还将缓存它使用这项服务。而且,如果它已被缓存,则不会创建新的API调用。好处是你永远不会遇到它返回的undefined的情况,因为你正在回复诺言。

在你的第一控制器,更新的代码变成:

app.controller("employeeBoxController", ['$scope', 'CacheAPIService', function($scope, CacheAPIService) { 
    $scope.getEmployeeDetails = function(eid) { 
    $scope.isLoading = true; 
    var endpoint = 'api/endpoint/'+$scope.eid; //Replace with your API endpoint 
    CacheAPIService.get(endpoint).then(function(result) { 
     $scope.isLoading = false; 
     console.log(dataService.getData('result')); 
    }) 
    } 
}]); 

在这里,第一个API调用是由和缓存。看看你的其他控制器:

app.controller("empController", ['$scope', 'CacheAPIService', function($scope, CacheAPIService) { 
    CacheAPIService.get(endpoint).then(function(data) { 
    var endpoint = 'api/endpoint/'+$scope.eid; //your API endpoint 
    console.log('data =', data); 
    }); 

}]); 

在这里,你仍然使用相同的服务,但它会被缓存,如果没有缓存,它会让API调用和缓存承诺。在这里,我直接使用API​​端点作为存储缓存的关键。这样您就不必每次都提供唯一的密钥,因为端点本身是唯一的。

注意的是,在要删除缓存数据,使得POST时或认沽认购的情况下,你可以调用CacheAPIService.clear(apiEndpoint)从缓存中清除细节。

+0

这是缓存api的好方法,但是我在employeeBoxController中设置的eid未定义,以及当我尝试在$ scope.eid中使用 – shashank

+0

这样您可以创建一个缓存服务,该服务还实现了获取数据的休息逻辑。 .. –

$ http.get将返回一个承诺。 要正确设置数据的DataService:

employeeService.getDetails($scope.eid).then(function(result) { 
     dataService.setData(result.data, 'result'); // note .data 
     $scope.isLoading = true; 
     console.log(dataService.getData('result')); 
    }) 

存放承诺在您的“缓存”服务是不是最好的选择。

我期望getEmployeeDetails()函数将会路由到empController,所以如果您仍然像前面所说的那样将$ promise存储在您的服务中,那么您可以这样做。

dataService.getData('result').then(function(result){ 
     $scope.result = result.data; 
    }); 

当$ scope.result设置为$ scope时,ng-repeat将开始迭代。

随着第一个修改建议,你并不需要接触empController但只是NG重复指令EMP-list.html有:

<tr ng-repeat="oemp in result"> 

重构HTTP调用与厂家的配方和$资源。 https://docs.angularjs.org/api/ngResource/service/ $ resource

这比编写提供程序更容易,更快捷。

+0

我debuged代码empController是在ajax调用发生之前执行,如上所述@Pankaj Parkar所以empController中的数据是不确定的,我不是确定多个视图如何工作我cilck按钮然后函数调用getEmployeeDetails()并发生ajax调用,但是如何首先将控制器empController初始化 – shashank

+0

事实是,$ http服务正在使用异步请求实际调用服务器端点。当然,你会首先得到控制器的执行(总是),但诺言应该以这种方式工作。无论如何,Angular会监视你的范围变量,并且在提供数据时会显示/解析它。我建议你阅读这篇文章。 http://robotlolita.me/2015/11/15/how-do-promises-work.html –

+0

如何在我的dataService中存储承诺,我是否应该再次使用$ http.get进行新的ajax调用 – shashank