简体   繁体   English

从角度控制器外部控制器设置范围变量

[英]set scope variable from outside controller in angular

Is it possible to set a $scope variable of a controller from outside the controller? 是否可以从控制器外部设置控制器的$ scope变量?

For example, if I have a controller: 例如,如果我有一个控制器:

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

}]);

And a function in the global scope which has an event handler. 以及具有事件处理程序的全局范围中的函数。 Now I want to set a $scope variable when that event happens. 现在我想在事件发生时设置$scope变量。 Is it possible? 可能吗? My global function: 我的全球职能:

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

We can use $injector for accessing Angular Services Outside Scope. 我们可以使用$injector来访问Angular Services Outside Scope。 For your example. 以你为榜样。

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

and in your controller you could use. 在您的控制器中,您可以使用。

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

    }
]);

DEMO DEMO

For more details view this 有关详细信息,请查看

Hope this helps 希望这可以帮助

use can use $rootScope like this. use可以像这样使用$ rootScope。

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

and use can access the variable in global function 并且use可以访问全局函数中的变量

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

You can try using $broadcast from the $rootscope to notify your controller that the event has occurred. 您可以尝试使用$ rootscope中的$ broadcast来通知您的控制器事件已经发生。

//rootscope
$rootscope.$broadcast("myevent",eventObjectToBePassed);

//your controller
$scope.$on("myevent",function(eventObject){

//do something

});

A cleaner way would be to inject rootscope in a service and create a sendEvent function to actually do $rootscope.$broadcast. 更简洁的方法是在服务中注入rootscope并创建一个sendEvent函数来实际执行$ rootscope。$ broadcast。

You should not use a global scope variable directly when working with angular apps. 使用角度应用程序时,不应直接使用全局范围变量。 The way it is recommended is to wrap this functionality in a directive and use the directive in your templates. 建议的方法是将此功能包装在指令中,并在模板中使用该指令。 This way you will hvae access to the $scope to update the value. 这样您就可以访问$scope来更新值。 Eg: 例如:

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

In your html, use the directive like this: 在您的html中,使用如下指令:

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

This will make the scope from the controller of the containing view available as scope within the directive 这将使包含视图的控​​制器的scope可用作指令中的scope

Refer these for best practices on using directives over direct dom manipulation and reusable functionality http://ng-learn.org/2014/01/Dom-Manipulations/ https://stackoverflow.com/a/15012542/3878940 有关使用直接dom操作和可重用功能的directives最佳实践,请参阅这些内容http://ng-learn.org/2014/01/Dom-Manipulations/ https://stackoverflow.com/a/15012542/3878940

I can think about two ways to do this 我可以考虑两种方法来做到这一点

  1. Use the $rootScope which is the easy way to do it. 使用$rootScope这是一种简单的方法。 But I personally don't like it to much if it isn't really a global variable. 但如果它不是真正的全局变量,我个人并不喜欢它。

  2. Write a Eventhandler and listen in the controller 编写一个Eventhandler并在控制器中监听

You can use var requiredElemScope = angular.element(ELEMENT_SELECTOR).scope(); 你可以使用var requiredElemScope = angular.element(ELEMENT_SELECTOR).scope(); to get the scope of the element. 获得元素的范围。 Then you can assign value to the scope variable as requiredElemScope.city = someValue; 然后你可以根据requiredElemScope.city = someValue;为范围变量赋值requiredElemScope.city = someValue;

Here ELEMENT_SELECTOR is the dom selector to which the controller is attached. 这里ELEMENT_SELECTOR是控制器所连接的dom选择器。

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

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