当多次调用Angular服务时,它会重写自身

Angular service overrides itself when called more than once

本文关键字:重写 调用 Angular 服务      更新时间:2023-09-26

我有一个聊天组件,它有该聊天的哈希id。我所有的api调用(由服务完成)都有一个哈希值。当我两次调用我的聊天组件时,第一个聊天的服务哈希值被第二个聊天覆盖。

angular.module('testModule', [])
  .controller('testController', function(testService, $scope) {
    var vm = this;
    vm.init = function() {
      vm.hash = vm.hash();
      testService.setHash(vm.hash);
    }
    vm.getServiceHash = function() {
      vm.serviceHash = testService.hash;
    }
    vm.init();
  })
  .service('testService', function() {
    var testService = {
      hash: null
    };
    testService.setHash = function(hash) {
      testService.hash = hash;
    }
    return testService;
  })
  .directive('test', function() {
    return {
      restrict: 'E',
      template: $("#test''.html").html(),
      controller: 'testController',
      controllerAs: 'test',
      bindToController: {
        hash: '&',
      },
      scope: {}
    }
  });
var app = angular.module('myApp', ['testModule']);
app.controller('myController', function($scope) {})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<body>
  <div ng-app="myApp" ng-controller="myController">
    <test hash="'123'"></test>
    <test hash="'321'"></test>
  </div>
  <script type="text/ng-template" id="test.html">
    <p>
      <h2> Controller hash: {{test.hash}} </h2>
      <button type="button" ng-click="test.getServiceHash()">Get service hash</button>
      <h2> Service hash: {{test.serviceHash }} </h2>
    </p>
  </script>
</body>

正如@jjmontes在评论中指出的那样,服务在Angular中是单例的。因此,它们不应该维护任何状态,除非该状态适用于所有消费者。例如,适用于所有消费者的公共数据集可以检索一次,然后由所有人使用,而不是再次进行可能代价高昂的调用。然而,任何特定于控制器的数据都应该保存在控制器中,并根据需要传递给服务。

特别是在你的例子中,你应该把它作为参数传递给控制器实例调用的服务方法,而不是在服务上设置哈希值。

.service('testService', function() {
  var testService = {
  };
  testService.callService = function(hash) {
    // call an API or whatever, passing the hash
  }
  return testService;
})