AngularJS: How can I pass variables between controllers?

后端 未结 16 2598
误落风尘
误落风尘 2020-11-22 00:31

I have two Angular controllers:

function Ctrl1($scope) {
    $scope.prop1 = \"First\";
}

function Ctrl2($scope) {
    $scope.prop2 = \"Second\";
    $scope.         


        
相关标签:
16条回答
  • 2020-11-22 01:11

    If you don't want to make service then you can do like this.

    var scope = angular.element("#another ctrl scope element id.").scope();
    scope.plean_assign = some_value;
    
    0 讨论(0)
  • 2020-11-22 01:15

    Solution without creating Service, using $rootScope:

    To share properties across app Controllers you can use Angular $rootScope. This is another option to share data, putting it so that people know about it.

    The preferred way to share some functionality across Controllers is Services, to read or change a global property you can use $rootscope.

    var app = angular.module('mymodule',[]);
    app.controller('Ctrl1', ['$scope','$rootScope',
      function($scope, $rootScope) {
        $rootScope.showBanner = true;
    }]);
    
    app.controller('Ctrl2', ['$scope','$rootScope',
      function($scope, $rootScope) {
        $rootScope.showBanner = false;
    }]);
    

    Using $rootScope in a template (Access properties with $root):

    <div ng-controller="Ctrl1">
        <div class="banner" ng-show="$root.showBanner"> </div>
    </div>
    
    0 讨论(0)
  • 2020-11-22 01:17

    Couldn't you also make the property part of the scopes parent?

    $scope.$parent.property = somevalue;
    

    I'm not saying it's right but it works.

    0 讨论(0)
  • 2020-11-22 01:17

    There are two ways to do this

    1) Use get/set service

    2) $scope.$emit('key', {data: value}); //to set the value

     $rootScope.$on('key', function (event, data) {}); // to get the value
    
    0 讨论(0)
  • 2020-11-22 01:19

    One way to share variables across multiple controllers is to create a service and inject it in any controller where you want to use it.

    Simple service example:

    angular.module('myApp', [])
        .service('sharedProperties', function () {
            var property = 'First';
    
            return {
                getProperty: function () {
                    return property;
                },
                setProperty: function(value) {
                    property = value;
                }
            };
        });
    

    Using the service in a controller:

    function Ctrl2($scope, sharedProperties) {
        $scope.prop2 = "Second";
        $scope.both = sharedProperties.getProperty() + $scope.prop2;
    }
    

    This is described very nicely in this blog (Lesson 2 and on in particular).

    I've found that if you want to bind to these properties across multiple controllers it works better if you bind to an object's property instead of a primitive type (boolean, string, number) to retain the bound reference.

    Example: var property = { Property1: 'First' }; instead of var property = 'First';.


    UPDATE: To (hopefully) make things more clear here is a fiddle that shows an example of:

    • Binding to static copies of the shared value (in myController1)
      • Binding to a primitive (string)
      • Binding to an object's property (saved to a scope variable)
    • Binding to shared values that update the UI as the values are updated (in myController2)
      • Binding to a function that returns a primitive (string)
      • Binding to the object's property
      • Two way binding to an object's property
    0 讨论(0)
  • 2020-11-22 01:20

    --- I know this answer is not for this question, but I want people who reads this question and want to handle Services such as Factories to avoid trouble doing this ----

    For this you will need to use a Service or a Factory.

    The services are the BEST PRACTICE to share data between not nested controllers.

    A very very good annotation on this topic about data sharing is how to declare objects. I was unlucky because I fell in a AngularJS trap before I read about it, and I was very frustrated. So let me help you avoid this trouble.

    I read from the "ng-book: The complete book on AngularJS" that AngularJS ng-models that are created in controllers as bare-data are WRONG!

    A $scope element should be created like this:

    angular.module('myApp', [])
    .controller('SomeCtrl', function($scope) {
      // best practice, always use a model
      $scope.someModel = {
        someValue: 'hello computer'
      });
    

    And not like this:

    angular.module('myApp', [])
    .controller('SomeCtrl', function($scope) {
      // anti-pattern, bare value
      $scope.someBareValue = 'hello computer';
      };
    });
    

    This is because it is recomended(BEST PRACTICE) for the DOM(html document) to contain the calls as

    <div ng-model="someModel.someValue"></div>  //NOTICE THE DOT.
    

    This is very helpful for nested controllers if you want your child controller to be able to change an object from the parent controller....

    But in your case you don't want nested scopes, but there is a similar aspect to get objects from services to the controllers.

    Lets say you have your service 'Factory' and in the return space there is an objectA that contains objectB that contains objectC.

    If from your controller you want to GET the objectC into your scope, is a mistake to say:

    $scope.neededObjectInController = Factory.objectA.objectB.objectC;
    

    That wont work... Instead use only one dot.

    $scope.neededObjectInController = Factory.ObjectA;
    

    Then, in the DOM you can call objectC from objectA. This is a best practice related to factories, and most important, it will help to avoid unexpected and non-catchable errors.

    0 讨论(0)
提交回复
热议问题