pagina - llamar funcion de otro controlador angularjs




AngularJS. Cómo llamar a la función del controlador desde fuera del componente del controlador (6)

¿Cómo puedo llamar a la función definida bajo el controlador desde cualquier lugar de la página web (fuera del componente del controlador)?

Funciona perfectamente cuando presiono el botón "get". Pero necesito llamarlo desde fuera del controlador div. La lógica es: por defecto mi div está oculto. En algún lugar del menú de navegación, presiono un botón y debería mostrar () mi div y ejecutar la función "get". ¿Cómo puedo lograr esto?

Mi página web es:

<div ng-controller="MyController">
  <input type="text" ng-model="data.firstname" required>
  <input type='text' ng-model="data.lastname" required>

  <form ng-submit="update()"><input type="submit" value="update"></form>
  <form ng-submit="get()"><input type="submit" value="get"></form>
</div>

Mi js:

   function MyController($scope) {
      // default data and structure
      $scope.data = {
        "firstname" : "Nicolas",
        "lastname" : "Cage"
      };

      $scope.get = function() {
        $.ajax({
           url: "/php/get_data.php?",
           type: "POST",
           timeout: 10000, // 10 seconds for getting result, otherwise error.
           error:function() { alert("Temporary error. Please try again...");},
           complete: function(){ $.unblockUI();},
           beforeSend: function(){ $.blockUI()},
           success: function(data){
            json_answer = eval('(' + data + ')');
            if (json_answer){
                $scope.$apply(function () {
                  $scope.data = json_answer;
            });
            }
        }
    });
  };

  $scope.update = function() {
    $.ajax({
        url: "/php/update_data.php?",
        type: "POST",
        data: $scope.data,
        timeout: 10000, // 10 seconds for getting result, otherwise error.
        error:function() { alert("Temporary error. Please try again...");},
        complete: function(){ $.unblockUI();},
        beforeSend: function(){ $.blockUI()},
        success: function(data){ }
      });
    };
   }

Aquí hay una manera de llamar a la función del controlador desde afuera:

angular.element(document.getElementById('yourControllerElementID')).scope().get();

donde get() es una función de su controlador.

Puedes cambiar

document.getElementById('yourControllerElementID')` 

a

$('#yourControllerElementID')

Si está usando jQuery.

Además, si su función significa cambiar algo en su Vista, debe llamar

angular.element(document.getElementById('yourControllerElementID')).scope().$apply();

para aplicar los cambios

Una cosa más, debe tener en cuenta es que los ámbitos se inicializan después de que se carga la página, por lo que los métodos de llamada desde fuera del alcance siempre se deben hacer después de que se cargue la página. De lo contrario, no llegarás al alcance en absoluto.

ACTUALIZAR:

Con las últimas versiones de angular, debes usar

angular.element(document.getElementById('yourControllerElementID')).injector().‌​get('$rootScope')

Y sí, esto es, de hecho, una mala práctica , pero a veces solo necesitas cosas rápidas y sucias.


Encontré un ejemplo en internet.

Un tipo escribió este código y trabajó perfectamente

HTML

<div ng-cloak ng-app="ManagerApp">
    <div id="MainWrap" class="container" ng-controller="ManagerCtrl">
       <span class="label label-info label-ext">Exposing Controller Function outside the module via onClick function call</span>
       <button onClick='ajaxResultPost("Update:Name:With:JOHN","accept",true);'>click me</button>
       <br/> <span class="label label-warning label-ext" ng-bind="customParams.data"></span>
       <br/> <span class="label label-warning label-ext" ng-bind="customParams.type"></span>
       <br/> <span class="label label-warning label-ext" ng-bind="customParams.res"></span>
       <br/>
       <input type="text" ng-model="sampletext" size="60">
       <br/>
    </div>
</div>

JAVASCRIPT

var angularApp = angular.module('ManagerApp', []);
angularApp.controller('ManagerCtrl', ['$scope', function ($scope) {

$scope.customParams = {};

$scope.updateCustomRequest = function (data, type, res) {
    $scope.customParams.data = data;
    $scope.customParams.type = type;
    $scope.customParams.res = res;
    $scope.sampletext = "input text: " + data;
};



}]);

function ajaxResultPost(data, type, res) {
    var scope = angular.element(document.getElementById("MainWrap")).scope();
    scope.$apply(function () {
    scope.updateCustomRequest(data, type, res);
    });
}

Demo

* Hice algunas modificaciones, ver original: font JSfiddle


La solución angular.element(document.getElementById('ID')).scope().get() dejó de funcionar para mí en angular 1.5.2. Mención aparte en un comentario de que esto tampoco funciona en 1.4.9. Lo arreglé guardando el alcance en una variable global:

var scopeHolder;
angular.module('fooApp').controller('appCtrl', function ($scope) {
    $scope = function bar(){
        console.log("foo");        
    };
    scopeHolder = $scope;
})

llamar desde un código personalizado:

scopeHolder.bar()

si quiere restringir el alcance a solo este método. Para minimizar la exposición de todo el alcance. usa la siguiente técnica.

var scopeHolder;
angular.module('fooApp').controller('appCtrl', function ($scope) {
    $scope.bar = function(){
        console.log("foo");        
    };
    scopeHolder = $scope.bar;
})

llamar desde un código personalizado:

scopeHolder()

Prefiero incluir la fábrica como dependencias en los controladores que inyectarlos con su propia línea de código: http://jsfiddle.net/XqDxG/550/

myModule.factory('mySharedService', function($rootScope) {
    return sharedService = {thing:"value"};
});

function ControllerZero($scope, mySharedService) {
    $scope.thing = mySharedService.thing;

ControllerZero. $ Inject = ['$ scope', 'mySharedService'];


Soy un usuario de framework Ionic y el que encontré que proporcionaría consistentemente el $ scope del controlador actual es:

angular.element(document.querySelector('ion-view[nav-view="active"]')).scope()

Sospecho que esto se puede modificar para adaptarse a la mayoría de los escenarios independientemente del marco (o no) al encontrar la consulta que se dirigirá a los elementos DOM específicos que están disponibles solo durante una instancia de controlador determinada.


Tengo múltiples rutas y múltiples controladores, así que no pude lograr que la respuesta aceptada funcionara. Encontré que agregar la función a la ventana funciona:

fooModule.controller("fooViewModel", function ($scope, fooService, $http, $q, $routeParams, $window, $location, viewModelHelper, $interval) {
    $scope.initFoo = function () {
        // do angular stuff
    }
    var initialize = function () {
        $scope.initFoo();
    }

    initialize();

    window.fooreinit = initialize;

}

Luego, fuera del controlador, esto se puede hacer:

function ElsewhereOnThePage() {
    if (typeof(fooreinit) == 'function') { fooreinit(); }
}




angularjs