$ watch和2个控制器

时间:2015-07-27 09:39:21

标签: javascript angularjs angularjs-scope

上下文

我有2个视图和3个控制器。

我想要的: 当我点击“settings.html”中的一个按钮时,我想在“settings.js”中更新我的变量'shopMarkers'(变量在“main.js”中定义),我也想在“map”中自动更新一个对象。 js“使用'shopMarkers'的新值更新,以在”map.html“中的地图中显示标记。

Settings.html

<div class="settings">

  <div class="row">

    <div class="question">
      Show shops ?
    </div>

    <div class="switch">
      <input id="toggle-1" class="toggle toggle-round" type="checkbox" ng-click="toggleShops()">
      <label for="toggle-1"></label>
    </div>

  </div>

</div>

Settings.js

'use strict';

/**
 * @ngdoc function
 * @name frontEndOpenEatApp.controller:SettingsCtrl
 * @description
 * # SettingsCtrl
 * Controller of the frontEndOpenEatApp
 */
angular.module('frontEndOpenEatApp')
  .controller('SettingsCtrl', ['$scope', 'shops', function ($scope, shops) {

    $scope.toggleShops = function() {
      if ($scope.$parent.shopMarkers.length == 0){
        shops.getShops().then(
          function (data){
            createMarkersForShops(data);
          }, function (msg) {
            console.log(msg);
          }
        );
      }
      else {
        $scope.$parent.shopMarkers = [];
      }
    };

    var createMarkersForShops = function (shops){
      var markers = [];
      for (var shop in shops) {
        var marker = {
          position : new google.maps.LatLng(shops[shop].latitude,shops[shop].longitude),
          title : shops[shop].description
        };
        markers.push(marker);
      }
      $scope.$parent.shopMarkers = markers;
    };

  }]);

map.html

<div id="loader" class="animated fadeIn">
  <i class="fa fa-cog fa-spin"></i>
</div>

<div id="map-canvas"></div>

map.js

'use strict';

/**
 * @ngdoc function
 * @name frontEndOpenEatApp.controller:MapCtrl
 * @description
 * # MapCtrl
 * Controller of the frontEndOpenEatApp
 */
angular.module('frontEndOpenEatApp')
  .controller('MapCtrl', ['$scope', 'shops', '$timeout', function ($scope, shops, $timeout) {

    var map;
    /**
     * Initialisation de la carte google map.
     */
    function initialize () {
      var mapOptions = {
        zoom: 18,
        center: new google.maps.LatLng(48.8879996, 2.2882407)
      };

      map = new google.maps.Map(document.getElementById('map-canvas'),
        mapOptions);

    }

    $scope.$parent.$watch($scope.shopMarkers, updateShopsMarkers, true);

    function updateShopsMarkers (){
      for (var shop in $scope.$parent.shopMarkers){
        var marker = new google.maps.Marker($scope.$parent.shopMarkers[shop]);
        marker.setMap(map);
      }
    }

  }]);

main.js

'use strict';

/**
 * @ngdoc function
 * @name frontEndOpenEatApp.controller:MainCtrl
 * @description
 * # MainCtrl
 * Controller of the frontEndOpenEatApp
 */
angular.module('frontEndOpenEatApp')
  .controller('MainCtrl', ['$scope', function ($scope) {
    $scope.shopMarkers = [];
  }]);

我希望我能正确描述我的问题。

PS:'商店'是我创建的服务,但我不认为更多地描述它。我使用了一些谷歌地图功能,但这不是问题,你可以忘记这些功能。我的问题实际上是关于从其他子控制器更新的父控制器的$ watch。 最后,我为任何不正确的拼写道歉。

3 个答案:

答案 0 :(得分:1)

您可以在$ rootScope中使shopMarkers变量可用,并且如果发生任何更改,它将相应地更改。

所以我建议注入$ rootScope服务并使用$ rootScope定义变量。

&#13;
&#13;
 $rootScope.shopMarkers = [];
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可以使用$scope.broadcast$scope.$on

执行此操作

在settings.js

angular.module('frontEndOpenEatApp')
  .controller('SettingsCtrl', ['$scope', 'shops', function ($scope, shops) {
    // watch for $scope.shopMarkers changes
    $scope.$watch('shopMarkers', function(newValue) {
      // broadcast an event telling that $scope.shopMarkers value has been changed
      $scope.boradcast('shopMarkersValueChanged', { value: newValue });
    });
}]);

在map.js

angular.module('frontEndOpenEatApp')
  .controller('MapCtrl', ['$scope', 'shops', '$timeout', function ($scope, shops, $timeout) {
  // listen for event "shopMarkersValueChanged"
  $scope.$on('shopMarkersValueChanged', function(event, args) {
    // update the value of $scope.shopMarkers with the value sent from "SettingsCtrl"
    $scope.shopMarkers = args.value;
  });
}]);

答案 2 :(得分:0)

我发现了我的错误:

在map.js中的

我写道:

$scope.$parent.$watch($scope.shopMarkers, updateShopsMarkers, true);

解决方案是:

$scope.$parent.$watch('shopMarkers', updateShopsMarkers, true);