繁体   English   中英

如何在角度服务之间正确共享数据

[英]How to properly share data between angular services

我试图重写一个大型复杂的表单,该表单在控制器中执行所有操作。 我首先将相关功能分为各自的模块/服务。 我不明白如何在不使控制器拥挤或不要求将过多参数传递给服务功能的情况下维护表单数据。

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

这是总结此方法的插件: https ://plnkr.co/edit/vyKtlXk8Swwf7xmoCJ4q

let app = angular.module('myApp', []);

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;
  }
}]);
app.service('storeService', ['productService', function(productService) {
  let states = [
    { name: 'SC', value: 'SC' },
    { name: 'GA', value: 'GA' },
    { name: 'LA', value: 'LA' }
  ];

  let selectedState = '';

  this.getAvailableStates = function() {
    return states;
  }

  this.setSelectedState = function(state) {
    selectedState = state;
  }

  this.getPrice = function() {
    // This console.log will always return undefined.
    // productService.selectedProduct is not available.
    console.log(productService.selectedProduct);
    if (productService.selectedProduct == "foo" && selectedState == 'SC') {
      return 10;
    }
    return 5;
  }
}]);
app.controller('myController', function($scope, storeService, productService) {
  $scope.name = '';
  $scope.deliveryState = '';
  $scope.selectedProduct = null;
  $scope.price = 0;

  $scope.productSelection = productService.getAvailableProducts();
  $scope.states = storeService.getAvailableStates();

  $scope.productChanged = function() {
    productService.setSelectedProduct($scope.selectedProduct);
    $scope.price = storeService.getPrice();
  }

  $scope.stateChanged = function() {
    storeService.setSelectedState($scope.deliveryState);
    $scope.price = storeService.getPrice();
  }
});

我正在尝试避免这样的事情:

$scope.price = storeService.getPrice(
     $scope.state,
     $scope.selectedProduct,
     $scope.servicePackage,
     $scope.serviceFee,
     $scope.shippingSelection,
     // etc…
);

我是否应该创建第三个服务来设置和获取其他服务上的所有数据?

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

为什么在注入的服务上访问变量时会出现undefined状态?

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;
  }

}]);

并使用吸气剂:

  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
);

该表单可以直接填充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... -->

在另一服务中计算某些内容之前,在一个服务中对变量进行设置会产生不良的耦合 ,从而使代码难以理解,调试,维护和测试。

取而代之的是,应该以连贯的方式将控制器需要的所有信息提供给定价服务。

您不应该注入$ scope,$ scope是开发AngularJs的一种过时的方式,您应该研究component或controllerAs语法。

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

服务应提供获取产品或创建新产品的数据功能,而控制器应执行类似的操作

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

要么

$ctrl.product = productService.get(productId);

然后在您看来,您绑定到产品的属性

<input name="name" ng-model="$ctrl.product.name">

当您保存产品时,会将整个过程传递回服务

<form name="productForm" ng-submit="productForm.$valid && $ctrl.save()">

并在控制器中

$ctrl.save = function() {
  productService.save($ctrl.product);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM