简体   繁体   中英

How to pass the selected value from different controllers in AngularJS

I have started to learn AngularJS yesterday. I am trying to use it to create a web application which uses a simple web service.

Right now I have three select boxes.

First select : orgType ->gets all orgType from the service at load (I got this working)

Second select: state-> populates a bunch of states from local json object(fine till here)

Third select: cities-> gets all the cities for the SELECTED state from the web service(this is where I am stuck I can't get the the third select to populate as state changes).

This is my code for now

HTML:

<body>
    <div  id='test'>

        <select class="form-control" ng-controller="typeController" >
            <option ng-repeat="types in row" >{{types.type}}</option>

        </select>

        <select class="form-control"   ng-controller="statesController" >
            <option ng-repeat="state in states" >{{state.abbreviation}}</option>

        </select>

        <select class="form-control" ng-controller="citiesController" >
            <option ng-repeat="city in cities" >{{city.city}}</option>

        </select>

    </div>  
</body>
</html> 

Controllers.js

    var myApp=angular.module('myApp',[]);

    myApp.controller('typeController',['$scope','$http',function ($scope,$http){
      $http.get('someURL path=%2FOrgTypes').success(function(data){
        var jsonData = $.xml2json(data);
        console.log(jsonData.row);
        $scope.row=jsonData.row;

      });
    }]);

    myApp.controller('statesController',['$scope','$http',function ($scope,$http){
      $http.get('data/states.json').success(function(data){

         console.log('states',data);
         $scope.states=data;

      });
    }]);

    myApp.controller('citiesController',['$scope','$http',function changeCity($scope,$http){
      $http.get('someURL ?path=/Cities?state=MD').success(function(data){
//hardcoding city to MD for now
           var jsonData = $.xml2json(data);
           console.log('cities', jsonData);
           $scope.cities=jsonData.row;
        });

    }]);

Thanks for your help!

create a service that stores your state abbreviation

.factory('myFactory', function() {
    var state = '';
    return {
        setState: function(val) {
            state = val;
        },
        getState: function() {
            return state;
        }
    }
}

then you can watch the getState function in this service in your controller.

$scope.$watch(function () {
  return myFactory.getState();
}, function (val) {
   // execute your get method with the new value or whatever you want to do
});

and of course make sure you inject all your dependencies appropriately.

further more why do all of these selects need their own controller? move all the http calls to services and have them all share the same scope.

Is there any specific reason you want so many controllers? For the simple page you have, one is enough. And ng-change is the right way to go. First thing you need to do is to add ng-model to the state and city selects so that we have something for 2-way binding. And then use ng-change on the state select to receive the selected state and do corresponding action there for the city.

Example

 <div ng-app="myApp" >
  <div ng-controller="myCtrl">
   <select class="form-control" ng-model="selectedState" ng-change="changedState(selectedState)">
     <option ng-repeat="state in states" >{{state.abbreviation}}</option>
   </select>
   <select class="form-control" ng-model="citiesController" >
     <option ng-repeat="city in cities" >{{city.city}}</option>
   </select>    
  </div>       
</div>

js:

myApp.controller('myCtrl', function($http, $scope){    
    $scope.changedState=function(selectedState){
      $http.get('url?state='+selectedState).success(data){
          $scope.cities = data;
      };
    }       
}

Or you can create a watch function for the selectedState to achieve the same thing. Hope this help~

If you are trying to access the data from a url which is different than the domain your page is, you might be hitting the Same Origin Policy problem. Basically this is not a problem, but a security feature where a web browser permits scripts contained in web page A to access data in a web page B, but only if both web pages have the same origin. An origin is defined as a combination of URI scheme, hostname, and port number .

One typical solution to deal with this problem is to pass a callback function name in the url of the web service.

somewebapiendpoint?callback=some_function_name

Provided the webapi endpoint will return the result wrapped inside some_function_name script. Since the server can execute script inside your page, you should be careful (basically trust the server :)) about this approach.

Another solution is to enable CORS

In order to share data between controllers, you should create a service. However, in this case I would have a single controller on <div id="test"> that would have access to each of the select elements' ngModels.

<body>
    <div id="test" ng-controller="MyFormController">
        <select class="form-control" ng-model="type">
            <option ng-repeat="types in row" >{{types.type}}</option>
        </select>

        <select class="form-control" ng-model="state">
            <option ng-repeat="state in states" >{{state.abbreviation}}</option>
        </select>

        <select class="form-control" ng-model="city">
            <option ng-repeat="city in cities" >{{city.city}}</option>
        </select>
    </div>  
</body>

Also, consider using the controllerAs syntax . It's better to keep your data out of the $scope , as it helps separate concerns and is more in line with Angular2 architecture.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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