【问题标题】:Updating shared data between controllers更新控制器之间的共享数据
【发布时间】:2017-01-06 05:09:27
【问题描述】:

我正在尝试实现 AngularJS 控制器之间的数据共享,我遵循了一种在两个控制器之间共享服务实例的方法,并且没有问题,来自变量的数据显示出来。但是,现在我需要更新服务中的变量,以便更改将被各种控制器复制,因此注入相同服务的任何控制器都具有相同的数据。

这是我的尝试...

HTML 模板

<h1>Services data sharing</h1>
<div ng-controller="OrderListController as vm">
  <h3>Orders list</h3>
  <table>
    <tr>
      <th>Item name</th>
      <th>Total</th>
    </tr>
    <tr ng-repeat="order in vm.orders" ng-click="vm.selectOrder(order.id)">
      <td ng-bind="order.item"></td>
      <td ng-bind="order.total | currency"></td>
    </tr>
  </table>
  <p><i>Click an order to see it's details.</i></p>
</div>
<div ng-controller="OrderShowController as vm">
  <h3>Order detail</h3>
  <p>
    <b>ID: </b><span ng-bind="vm.order.id"></span>
  </p>
  <p>
    <b>Item name: </b><span ng-bind="vm.order.item"></span>
  </p>
  <p>
    <b>Total: </b><span ng-bind="vm.order.total | currency"></span>
  </p>
</div>

JavaScript 文件

'use strict';

angular
    .module('orderCrud', [])
    .service('OrderService', function() {

        this.selected = {};

        var orders = [{
            id: 1,
            item: 'Hamburger',
            total: 5.15
        }, {
            id: 2,
            item: 'Nachos',
            total: 2.75
        }, {
            id: 3,
            item: 'Hot Dog',
            total: 3.50
        }];

        function getOrders() {

            return orders;
        }

        function setSelected(id) {

            for (var i = orders.length - 1; i >= 0; i--) {

                if (orders[i].id === id) {
                    this.selected = orders[i];
                    console.log(this.selected);
                    break;
                }
            }
        }

        return {
            get: getOrders,
            setSelected: setSelected
        };
    })
    .controller('OrderListController', function(OrderService) {

        var vm = this;

        vm.orders = OrderService.get();

        vm.selectOrder = function(id) {

            OrderService.setSelected(id);
        };

        vm.selectOrder(angular.copy(vm.orders).shift().id);
    })
    .controller('OrderShowController', function(OrderService) {

        var vm = this;

        vm.order = OrderService.selected;
    });

I've created a Plunker if you need it.

目标是在模板的详细信息侧显示所选订单,如果在列表中的表格中单击另一个订单,则应更改该订单。您可能会注意到,我不是控制器中 $scope$rootScope 的粉丝,如果在不注入这些作用域的情况下无法实现这一点,请告诉我。

任何帮助将不胜感激,谢谢!

【问题讨论】:

  • 你检查我的答案了吗?
  • 我做到了,请参阅下面的评论。

标签: javascript angularjs angular-services angular-controller data-sharing


【解决方案1】:

我做了一些代码更改:

  • 在服务的setOrders 方法中使用了javaScript filter() 方法而不是for loop
  • 使用$scope.$watch函数根据旧值和新值的变化将服务数据反映到另一个控制器中。

工作演示:

angular
  .module('orderCrud', [])
  .service('OrderService', function() {
    
    this.selected = {};
    
    var orders = [{
      id: 1,
      item: 'Hamburger',
      total: 5.15
    }, {
      id: 2,
      item: 'Nachos',
      total: 2.75
    }, {
      id: 3,
      item: 'Hot Dog',
      total: 3.50
    }];
    
    var selectedOrder = [];
    
    this.getOrders = function() {
      
      return orders;
    }
    
    this.getSelectedOrder = function() {
      return selectedOrder;
    }
    
    this.setOrders = function(id) {
          this.order = orders.filter(function(item) {
            return item.id === id;
          });
          selectedOrder = this.order[0];
    }
    
  })
  .controller('OrderListController', function($scope, OrderService) {
    
    $scope.orderServ = OrderService;
    var vm = this;
    
    vm.orders = $scope.orderServ.getOrders();
    
    vm.selectOrder = function(id) {
      $scope.orderServ.setOrders(id);
    };
    
  }).controller('OrderShowController', function($scope, OrderService) {
    
    var vm = this;
    
    $scope.orderServ = OrderService;
    
    $scope.$watch(function () { return $scope.orderServ.getSelectedOrder(); }, function (newValue, oldValue) {
        if (newValue !== oldValue) vm.order = newValue;
    });
    
  });
table {
    font-family: arial, sans-serif;
    border-collapse: collapse;
    width: 100%;
}

td, th {
    border: 1px solid #dddddd;
    text-align: left;
    padding: 8px;
}

tr:nth-child(even) {
    background-color: #dddddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="orderCrud">
    <h1>Services data sharing</h1>
    <div ng-controller="OrderListController as vm">
      <h3>Orders list</h3>
      <table>
        <tr>
          <th>Item name</th>
          <th>Total</th>
        </tr>
        <tr ng-repeat="order in vm.orders" ng-click="vm.selectOrder(order.id)">
          <td ng-bind="order.item"></td>
          <td ng-bind="order.total | currency"></td>
        </tr>
      </table>
      <p><i>Click an order to select it.</i></p>
      </div>
<div ng-controller="OrderShowController as vm">
      <h3>Order detail</h3>
      <p>
        <b>ID: </b><span ng-bind="vm.order.id"></span>
      </p>
      <p>
        <b>Item name: </b><span ng-bind="vm.order.item"></span>
      </p>
      <p>
        <b>Total: </b><span ng-bind="vm.order.total | currency"></span>
      </p>
          </div>
  </body>

【讨论】:

  • 感谢您的回复,但我一直在寻找一种解决方案,它使用两个可以共享 selectedOrder 值的独立控制器。无论如何,我明白你对每个视图都有一个控制器是什么意思。
  • @CatBrownie 感谢您纠正我。我根据要求更新了我的答案,请立即检查。现在使用两个单独的控制器可以正常工作。
猜你喜欢
  • 2013-08-14
  • 2015-03-15
  • 2015-12-15
  • 2014-03-22
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
  • 2016-11-30
  • 1970-01-01
相关资源
最近更新 更多