简体   繁体   中英

Call function of a controller within an outside controller directive

I am creating an ionic application that works with research and routes on a map. You enter the location you want and it already gives you the route from your current location to the desired location. It's working perfectly. The only problem is that I need call a function that is within the map controller and I need this function to run after the work of the directive that is outside of the controller. In simple terms, I need to call a function of a controller within a directive. I saw some examples on the internet and here in the SO but with none of these examples I could succeed, I hope you can help me.

example:

.controller("atigmaps", function($ scope, $ state, $ ionicModal, $ rootScope) {
    $ Scope.load_map = function() {
        /// ...    
    }
})

.directive('example', function($ ionicModal, LocationService) {
             $ Scope.choosePlace = function(place) {
                 LocationService.getDetails(place.place_id).then(function(location) {
                     $ Scope.location = location;
                     $ Scope.close();
                     $ Scope.load_map() < -- - This

                 function is within the controller
             });
         };
     }

My Function

var geocoder;
var map;
var marker;



geocoder = new google.maps.Geocoder();

    marker = new google.maps.Marker({
        map: $scope.model.myMap,
        draggable: true,
        icon:'pin_route.png',
    });





function carregarNoMapa(endereco) {

        geocoder.geocode({ 'address': endereco + ', Brasil', 'region': 'BR' }, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                if (results[0]) {
                    var latitude = results[0].geometry.location.lat();
                    var longitude = results[0].geometry.location.lng();

                    $('#txtEndereco').val(results[0].formatted_address);
                    $('#txtLatitude').val(latitude);
                    $('#txtLongitude').val(longitude);
                    $('#dest').val(document.getElementById('txtEndereco').value);





                    $scope.atualizalocation();

                    var location = new google.maps.LatLng(latitude, longitude);
                    marker.setPosition(location);
                    $scope.calcRoute();
                    $scope.model.myMap.setCenter(location);
                    $scope.model.myMap.setZoom(15);

                }
            }
        });
    }

My Directive

.directive('locationSuggestion', function($ionicModal, LocationService){
  return {
    restrict: 'A',
    scope: {
      location: '='
    },
    link: function($scope, element){
      console.log('locationSuggestion started!');
      $scope.search = {};
      $scope.search.suggestions = [];
      $scope.search.query = "";
      $ionicModal.fromTemplateUrl('location.html', {
        scope: $scope,
        focusFirstInput: true
      }).then(function(modal) {
        $scope.modal = modal;
      });
      element[0].addEventListener('focus', function(event) {
        $scope.open();
      });
      $scope.$watch('search.query', function(newValue) {
        if (newValue) {
          LocationService.searchAddress(newValue).then(function(result) {
            $scope.search.error = null;
            $scope.search.suggestions = result;
          }, function(status){
            $scope.search.error = "There was an error :( " + status;
          });
        };
        $scope.open = function() {
          $scope.modal.show();
        };
        $scope.close = function() {
          $scope.modal.hide();
        };






        $scope.choosePlace = function(place) {
          LocationService.getDetails(place.place_id).then(function(location) {
            $scope.location = location;
            $scope.close();








          });
        };
      });
    }
  }




})

You should include your function inside a factory, include the factory in your controller and directive, and call the function like: MyFactory.load_map()

Sample:

factory.js

angular.module('starter.factoryServices', [])

  .factory('MyFactory', function($q) {

    return {
          load_map : function() {
               /// ...    
           }
      }


  });

Your code:

.controller("atigmaps", function($ scope, $ state, $ ionicModal, $ rootScope, MyFactory) {

})

.directive('example', function($ ionicModal, LocationService, MyFactory) {
             $ Scope.choosePlace = function(place) {
                 LocationService.getDetails(place.place_id).then(function(location) {
                     $ Scope.location = location;
                     $ Scope.close();
                     MyFactory.load_map(); 

             });
         };
     }

And in your angular module:

angular.module('starter', ['ionic', 'starter.factoryServices'])

And the index.html, add the reference

<script src="path/myFactory.js"></script>

Assuming that the directive you talk about is yours, you could use the '&' symbol to expose the controller api (see here for documentation, it says "component" but it works with directives too). Here is an example of a directive I use:

(function() {
  'use strict';

  angular
    .module('app')
    .directive('tabs', tabs);

  /** @ngInject */
  function tabs() {
    var directive = {
      templateUrl: 'app/components/tabs/tabs.component.html',
      controller: 'TabsController',
      controllerAs: 'vm',
      bindToController: {
        id: '@',
        onApiReady: '&'
      },
      scope:{}
    };

    return directive;
  }
})();

And here is the associated controller:

(function() {
  'use strict';

  angular
    .module('app')
    .controller('TabsController', TabsController);

  /** @ngInject */
  function TabsController(TabList) {
    var vm = this, api;
    vm.$onInit = activate;

    api = {
      addTab: addTab
    };

    ////////////////////////////////////////////

    function activate() {
      vm.tabList = new TabList(vm.id);

      if(vm.onApiReady){
        vm.onApiReady({api: api});
      }
    }

    function addTab(tab) {
      vm.tabList.addTab(tab);
    }
  }
})();

Here is the HTML that call the directive I created

<div ng-controller="MainController as vm">
    <tabs id="main-tabs" on-api-ready="vm.onTabsApiReady(api)"></tabs>
</div>

And finally the MainController

(function() {
  'use strict';

  angular
    .module('app')
    .controller('MainController', MainController);

  /** @ngInject */
  function MainController(mainService) {
    var vm;
    vm = this;
    vm.$onInit = activate;
    vm.onTabsApiReady = onTabsApiReady;

    ///////////////////////////////////////

    function activate() {}

    function onTabsApiReady(tabList){
      var i, tabs = ['tab1','tab2'];

      for(i = 0 ; i < tabs.length ; ++i){
        tabList.addTab(tabs[i]);
      }
    }

  }
})();

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