Javascript 如何在angular services之间正确共享数据

Javascript 如何在angular services之间正确共享数据,javascript,angularjs,angularjs-service,Javascript,Angularjs,Angularjs Service,我试图重写一个大型复杂表单,它在控制器中完成所有操作。我首先将相关功能分离到它们自己的模块/服务中我不明白如何在不占用控制器或不需要向服务函数传递过多参数的情况下维护表单数据。 我目前的方法是在服务上设置变量,然后在其他服务中使用该服务并尝试访问保存的数据。这似乎不起作用。我认为这是因为将服务注入到另一个实例中会创建一个没有所有保存值的新实例 下面是一个plunker,总结了这种方法: 我试图避免这样的事情: $scope.price = storeService.getPrice(

我试图重写一个大型复杂表单,它在控制器中完成所有操作。我首先将相关功能分离到它们自己的模块/服务中我不明白如何在不占用控制器或不需要向服务函数传递过多参数的情况下维护表单数据。

我目前的方法是在服务上设置变量,然后在其他服务中使用该服务并尝试访问保存的数据。这似乎不起作用。我认为这是因为将服务注入到另一个实例中会创建一个没有所有保存值的新实例

下面是一个plunker,总结了这种方法:

我试图避免这样的事情:

$scope.price = storeService.getPrice(
     $scope.state,
     $scope.selectedProduct,
     $scope.servicePackage,
     $scope.serviceFee,
     $scope.shippingSelection,
     // etc…
);
$scope.price = storeService.getPrice(
     $scope.state,
     $scope.selectedProduct,
     $scope.servicePackage,
     $scope.serviceFee,
     $scope.shippingSelection,
     // etc…
);
我应该创建第三个服务来设置和获取其他服务上的所有数据吗


我应该维护控制器上的所有数据吗?

您不应该注入$scope,$scope是开发AngularJs的过时方法,您应该研究组件或ControllerA语法

控制器应仅在服务和视图之间编组数据

服务应提供数据功能,如获取产品或创建新产品,控制器应执行以下操作

$ctrl = this;
$ctrl.product = productService.new();

然后在您的视图中绑定到产品的属性

<input name="name" ng-model="$ctrl.product.name">
为什么在访问注入服务上的变量时会得到未定义的

let
声明创建一个私有变量

为变量添加一个getter:

app.service('productService', [function() {
  let products = [
    { name: 'foo', value: 'foo' },
    { name: 'bar', value: 'bar' },
    { name: 'baz', value: 'baz' }
  ];

  let selectedProduct = null;

  this.getAvailableProducts = function() {
    return products;
  }

  this.setSelectedProduct = function(product) {
    selectedProduct = product;
  }

  //ADD getter

  this.getSelectedProduct = function() {
      return selectedProduct;
  }

}]);
并使用getter:

  this.getPrice = function() {
    // This console.log will always return undefined.
    // productService.selectedProduct is not available.
    console.log(productService.selectedProduct);
     ̶i̶f̶ ̶(̶p̶r̶o̶d̶u̶c̶t̶S̶e̶r̶v̶i̶c̶e̶.̶s̶e̶l̶e̶c̶t̶e̶d̶P̶r̶o̶d̶u̶c̶t̶ ̶=̶=̶ ̶"̶f̶o̶o̶"̶ ̶&̶&̶ ̶s̶e̶l̶e̶c̶t̶e̶d̶S̶t̶a̶t̶e̶ ̶=̶=̶ ̶'̶S̶C̶'̶)̶ ̶{̶
     if (productService.getSelectedProduct() == "foo" && selectedState == 'SC') {
      return 10;
    }
    return 5;
 }

更新 我的服务是应该这样沟通,还是有一种不同的、更被接受的方法

我试图避免这样的事情:

$scope.price = storeService.getPrice(
     $scope.state,
     $scope.selectedProduct,
     $scope.servicePackage,
     $scope.serviceFee,
     $scope.shippingSelection,
     // etc…
);
$scope.price = storeService.getPrice(
     $scope.state,
     $scope.selectedProduct,
     $scope.servicePackage,
     $scope.serviceFee,
     $scope.shippingSelection,
     // etc…
);
避免这种情况的一种方法是使用对象作为参数来提供多个选项:

$scope.options = {};

$scope.price = storeService.getPrice(
     $scope.selectedProduct,
     $scope.options
);
表单可以直接填充
选项
对象:

<select ng-model="options.state">
    <option ng-repeat="state in states">{{ state.name }}</option>
</select><br>

<select ng-model="options.serviceFee">
    <option ng-repeat="fee in feeList">{{ fee.name }}</option>
</select><br>

<!-- //etc... -->

{{state.name}

{{fee.name}

在计算另一个服务中的某些内容之前,在一个服务中设置一个变量会产生一个不希望出现的问题,这使得代码难以理解、调试、维护和测试


相反,控制器需要的所有信息应以某种方式提供给定价服务。

服务是单例的。在多个位置注入它们总是返回同一个对象。@georgeawg如果它们是同一个对象,为什么在注入的服务上访问变量时会未定义?这确实允许我检索值。这是处理事情的正确方法吗?我的服务是应该这样通信还是有一种不同的、更被接受的方法?在计算另一个服务中的某些内容之前,在一个服务中设置一个变量会产生一种不希望出现的错误,使代码难以理解、调试、维护和测试。请参阅答案的更新。
  this.getPrice = function() {
    // This console.log will always return undefined.
    // productService.selectedProduct is not available.
    console.log(productService.selectedProduct);
     ̶i̶f̶ ̶(̶p̶r̶o̶d̶u̶c̶t̶S̶e̶r̶v̶i̶c̶e̶.̶s̶e̶l̶e̶c̶t̶e̶d̶P̶r̶o̶d̶u̶c̶t̶ ̶=̶=̶ ̶"̶f̶o̶o̶"̶ ̶&̶&̶ ̶s̶e̶l̶e̶c̶t̶e̶d̶S̶t̶a̶t̶e̶ ̶=̶=̶ ̶'̶S̶C̶'̶)̶ ̶{̶
     if (productService.getSelectedProduct() == "foo" && selectedState == 'SC') {
      return 10;
    }
    return 5;
 }
$scope.price = storeService.getPrice(
     $scope.state,
     $scope.selectedProduct,
     $scope.servicePackage,
     $scope.serviceFee,
     $scope.shippingSelection,
     // etc…
);
$scope.options = {};

$scope.price = storeService.getPrice(
     $scope.selectedProduct,
     $scope.options
);
<select ng-model="options.state">
    <option ng-repeat="state in states">{{ state.name }}</option>
</select><br>

<select ng-model="options.serviceFee">
    <option ng-repeat="fee in feeList">{{ fee.name }}</option>
</select><br>

<!-- //etc... -->