将外部控制器的范围变量设置为角度

set scope variable from outside controller in angular

本文关键字:设置 变量 范围 外部 控制器      更新时间:2023-09-26

是否可以从控制器外部设置控制器的$scope变量?

例如,如果我有一个控制器:

app.controller('citySelectCtrl', ['$scope',function($scope){
}]);

以及全局作用域中具有事件处理程序的函数。现在,我想在该事件发生时设置一个$scope变量。有可能吗?我的全局功能:

function initAutocomplete() {
    autocomplete = new google.maps.places.Autocomplete(
        /** @type {!HTMLInputElement} */(document.getElementById('autocomplete')),
        {
            componentRestrictions: {'country': 'in'},
            types: ['(cities)']
        });
    map = new google.maps.Map(document.getElementById('map'), {
        center: {lat: 22.5937, lng: 78.9629},
        zoom: 5,
        minZoom: 5
    });
}
autocomplete.addListener('place_changed', function() {
    infowindow.close();
    marker.setVisible(false);
    var place = autocomplete.getPlace();
    if (!place.geometry) {
      window.alert("Autocomplete's returned place contains no geometry");
      return;
    }
    // If the place has a geometry, then present it on a map.
    if (place.geometry.viewport) {
      map.fitBounds(place.geometry.viewport);
    } else {
      map.setCenter(place.geometry.location);
      map.setZoom(17);  // Why 17? Because it looks good.
    }
----------------------------------------------------------
    //SET $scope.city = place here
----------------------------------------------------------
    infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address);
    infowindow.open(map, marker);
  });

我们可以使用$injector访问范围外的Angular Services。以你为例。

// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
  map.fitBounds(place.geometry.viewport);
} else {
  map.setCenter(place.geometry.location);
  map.setZoom(17);  // Why 17? Because it looks good.
}
----------------------------------------------------------
    var elem = angular.element(document.querySelector('[ng-app]'));
    var injector = elem.injector();
     var $rootScope = injector.get('$rootScope');   
     $rootScope.$apply(function(){
       $rootScope.city = place //or city;
     });
----------------------------------------------------------
infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address);
infowindow.open(map, marker);
});

在你的控制器中你可以使用。

app.controller('citySelectCtrl', ['$scope','$rootScope',
    function ($scope,$rootScope) {         
         $rootScope.city = {};
    }
]);

演示

有关更多详细信息,请查看此

希望这能帮助

您可以尝试从$rootscope使用$broadcast来通知您的控制器事件已经发生。

//rootscope
$rootscope.$broadcast("myevent",eventObjectToBePassed);
//your controller
$scope.$on("myevent",function(eventObject){
//do something
});

更干净的方法是在服务中注入rootscope,并创建一个sendEvent函数来实际执行$rootscope$广播

使用角度应用程序时,不应直接使用全局范围变量。建议将此功能封装在指令中,并在模板中使用该指令。通过这种方式,您可以访问$scope来更新值。例如:

angular.directive('mapAutoComplete', function () {
  return {
    restrict: 'E',
    link: function (scope, elem, attr) {
      // Add your map and autocomplete here
      // Now you can use the `scope` to update the $scope of the parent controller
    }
  }
});

在html中,使用如下指令:

<map-auto-complete></map-auto-complete>

这将使包含视图的控制器的范围在指令中可用为scope

有关在直接dom操作和可重用功能上使用directives的最佳实践,请参阅以下内容http://ng-learn.org/2014/01/Dom-Manipulations/https://stackoverflow.com/a/15012542/3878940

我可以考虑两种方法来完成

  1. 使用$rootScope,这是一种简单的方法。但如果它不是一个真正的全局变量,我个人不太喜欢它。

  2. 编写事件处理程序并在控制器中侦听

use可以像这样使用$rootScope。

app.controller('citySelectCtrl', ['$scope', '$rootScope', function($scope, $rootScope){
    //$rootScope.city = place here;
}]);

并且使用可以访问全局函数中的变量

function initAutocomplete() {
    //$rootScope.city = place here;
}

您可以使用var requiredElemScope = angular.element(ELEMENT_SELECTOR).scope();来获取元素的作用域。然后可以将范围变量的值指定为requiredElemScope.city = someValue;

这里ELEMENT_SELECTOR是控制器所连接到的dom选择器。