javascript - w3schools - what is directive in angularjs




Um controlador AngularJS pode chamar outro? (9)

A seguir está uma abordagem de publish-subscribe que é independente do Angular JS.

Pesquisar Param Controller

//Note: Multiple entities publish the same event
regionButtonClicked: function () 
{
        EM.fireEvent('onSearchParamSelectedEvent', 'region');
},

plantButtonClicked: function () 
{
        EM.fireEvent('onSearchParamSelectedEvent', 'plant');
},

Pesquisa Choices Controller

//Note: It subscribes for the 'onSearchParamSelectedEvent' published by the Search Param Controller
localSubscribe: function () {
        EM.on('onSearchParamSelectedEvent', this.loadChoicesView, this);

});


loadChoicesView: function (e) {

        //Get the entity name from eData attribute which was set in the event manager
        var entity = $(e.target).attr('eData');

        console.log(entity);

        currentSelectedEntity = entity;
        if (entity == 'region') {
            $('.getvalue').hide();
            this.loadRegionsView();
            this.collapseEntities();
        }
        else if (entity == 'plant') {
            $('.getvalue').hide();
            this.loadPlantsView();
            this.collapseEntities();
        }


});

Gerente de eventos

myBase.EventManager = {

    eventArray:new Array(),


    on: function(event, handler, exchangeId) {
        var idArray;
        if (this.eventArray[event] == null) {
            idArray = new Array();
        } else { 
            idArray = this.eventArray[event];
        }
        idArray.push(exchangeId);
        this.eventArray[event] = idArray;

        //Binding using jQuery
        $(exchangeId).bind(event, handler);
    },

    un: function(event, handler, exchangeId) {

        if (this.eventArray[event] != null) {
            var idArray = this.eventArray[event];
            idArray.pop(exchangeId);
            this.eventArray[event] = idArray;

            $(exchangeId).unbind(event, handler);
        }
    },

    fireEvent: function(event, info) {
        var ids = this.eventArray[event];

        for (idindex = 0; idindex < ids.length; idindex++) {
            if (ids[idindex]) {

                //Add attribute eData
                $(ids[idindex]).attr('eData', info);
                $(ids[idindex]).trigger(event);
            }
        }
    }
};

Global

var EM = myBase.EventManager;

É possível ter um controlador usando outro?

Por exemplo:

Este documento HTML simplesmente imprime uma mensagem entregue pelo controlador MessageCtrl no arquivo messageCtrl.js .

<html xmlns:ng="http://angularjs.org/">
<head>
    <meta charset="utf-8" />
    <title>Inter Controller Communication</title>
</head>
<body>
    <div ng:controller="MessageCtrl">
        <p>{{message}}</p>
    </div>

    <!-- Angular Scripts -->
    <script src="http://code.angularjs.org/angular-0.9.19.js" ng:autobind></script>
    <script src="js/messageCtrl.js" type="text/javascript"></script>
</body>
</html>

O arquivo do controlador contém o seguinte código:

function MessageCtrl()
{
    this.message = function() { 
        return "The current date is: " + new Date().toString(); 
    };
}

Que simplesmente imprime a data atual;

Se eu fosse adicionar outro controlador, DateCtrl , que entregou a data em um formato específico de volta ao MessageCtrl , como alguém faria isso? A estrutura de DI parece estar preocupada com XmlHttpRequests e acessar serviços.


Aqui está um exemplo de uma página de dois controladores que compartilham dados de serviço:

<!doctype html>
<html ng-app="project">
<head>
    <title>Angular: Service example</title>
    <script src="http://code.angularjs.org/angular-1.0.1.js"></script>
    <script>
var projectModule = angular.module('project',[]);

projectModule.factory('theService', function() {  
    return {
        thing : {
            x : 100
        }
    };
});

function FirstCtrl($scope, theService) {
    $scope.thing = theService.thing;
    $scope.name = "First Controller";
}

function SecondCtrl($scope, theService) {   
    $scope.someThing = theService.thing; 
    $scope.name = "Second Controller!";
}
    </script>
</head>
<body>  
    <div ng-controller="FirstCtrl">
        <h2>{{name}}</h2>
        <input ng-model="thing.x"/>         
    </div>

    <div ng-controller="SecondCtrl">
        <h2>{{name}}</h2>
        <input ng-model="someThing.x"/>             
    </div>
</body>
</html>

Também aqui: https://gist.github.com/3595424


Eu não sei se isso está fora dos padrões, mas se você tem todos os seus controladores no mesmo arquivo, então você pode fazer algo assim:

app = angular.module('dashboardBuzzAdmin', ['ngResource', 'ui.bootstrap']);

var indicatorsCtrl;
var perdiosCtrl;
var finesCtrl;

app.controller('IndicatorsCtrl', ['$scope', '$http', function ($scope, $http) {
  indicatorsCtrl = this;
  this.updateCharts = function () {
    finesCtrl.updateChart();
    periodsCtrl.updateChart();
  };
}]);

app.controller('periodsCtrl', ['$scope', '$http', function ($scope, $http) {
  periodsCtrl = this;
  this.updateChart = function() {...}
}]);

app.controller('FinesCtrl', ['$scope', '$http', function ($scope, $http) {
  finesCtrl = this;
  this.updateChart = function() {...}
}]);

Como você pode ver os indicadoresCtrl está chamando as funções updateChart dos outros dois controladores ao chamar updateCharts.


Eu também sei disso.

angular.element($('#__userProfile')).scope().close();

Mas eu não uso muito, porque eu não gosto de usar seletores de jQuery em código angular.


Existem várias maneiras de se comunicar entre os controladores.

O melhor é provavelmente compartilhar um serviço:

function FirstController(someDataService) 
{
  // use the data service, bind to template...
  // or call methods on someDataService to send a request to server
}

function SecondController(someDataService) 
{
  // has a reference to the same instance of the service
  // so if the service updates state for example, this controller knows about it
}

Outra maneira é emitir um evento no escopo:

function FirstController($scope) 
{
  $scope.$on('someEvent', function(event, args) {});
  // another controller or even directive
}

function SecondController($scope) 
{
  $scope.$emit('someEvent', args);
}

Em ambos os casos, você pode se comunicar com qualquer diretiva também.



Se você quiser chamar um controlador para outro, existem quatro métodos disponíveis

  1. $ rootScope. $ emit () e $ rootScope. $ broadcast ()
  2. Se o segundo controlador for filho, você poderá usar a comunicação filho pai.
  3. Use os serviços
  4. Tipo de hack - com a ajuda de angular.element ()

1. $ rootScope. $ Emit () e $ rootScope. $ Broadcast ()

O controlador e seu escopo podem ser destruídos, mas o $ rootScope permanece em todo o aplicativo, e é por isso que estamos usando $ rootScope porque $ rootScope é o pai de todos os escopos.

Se você está realizando comunicação de pai para filho e até criança quer se comunicar com seus irmãos, você pode usar $ broadcast

Se você está realizando a comunicação de pai para filho, nenhum irmão invocado então você pode usar $ rootScope. $ Emit

HTML

<body ng-app="myApp">
    <div ng-controller="ParentCtrl" class="ng-scope">
      // ParentCtrl
      <div ng-controller="Sibling1" class="ng-scope">
        // Sibling first controller
      </div>
      <div ng-controller="Sibling2" class="ng-scope">
        // Sibling Second controller
        <div ng-controller="Child" class="ng-scope">
          // Child controller
        </div>
      </div>
    </div>
</body>

Código Angular

 var app =  angular.module('myApp',[]);//We will use it throughout the example 
    app.controller('Child', function($rootScope) {
      $rootScope.$emit('childEmit', 'Child calling parent');
      $rootScope.$broadcast('siblingAndParent');
    });

app.controller('Sibling1', function($rootScope) {
  $rootScope.$on('childEmit', function(event, data) {
    console.log(data + ' Inside Sibling one');
  });
  $rootScope.$on('siblingAndParent', function(event, data) {
    console.log('broadcast from child in parent');
  });
});

app.controller('Sibling2', function($rootScope) {
  $rootScope.$on('childEmit', function(event, data) {
    console.log(data + ' Inside Sibling two');
  });
  $rootScope.$on('siblingAndParent', function(event, data) {
    console.log('broadcast from child in parent');
  });
});

app.controller('ParentCtrl', function($rootScope) {
  $rootScope.$on('childEmit', function(event, data) {
    console.log(data + ' Inside parent controller');
  });
  $rootScope.$on('siblingAndParent', function(event, data) {
    console.log('broadcast from child in parent');
  });
});

No código acima, console de $ emit 'childEmit' não chamará dentro de irmãos filhos e chamará dentro de parent apenas, onde $ broadcast será chamado dentro de irmãos e pai também. Este é o lugar onde o desempenho entra em ação. preferível, se você estiver usando comunicação entre pais e filhos porque ele pula alguns cheques sujos.

2. Se o Segundo controlador for filho, você poderá usar a comunicação Pai-Filho

É um dos melhores métodos, Se você quiser fazer uma comunicação pai / mãe onde a criança queira se comunicar com um pai imediato , ela não precisará de nenhum tipo de transmissão ou emissão, mas se você quiser fazer a comunicação de pai para filho, então você precisa usar serviço ou $ broadcast

Por exemplo HTML: -

<div ng-controller="ParentCtrl">
 <div ng-controller="ChildCtrl">
 </div>
</div>

Angularjs

 app.controller('ParentCtrl', function($scope) {
   $scope.value='Its parent';
      });
  app.controller('ChildCtrl', function($scope) {
   console.log($scope.value);
  });

Sempre que você estiver usando comunicação entre pai e filho, Angularjs irá procurar por uma variável dentro do filho, se ele não estiver presente dentro dele, ele escolherá ver os valores dentro do controlador pai.

Serviços 3.Use

O AngularJS suporta os conceitos de "Separação de Preocupações" usando a arquitetura de serviços. Os serviços são funções javascript e são responsáveis ​​por executar apenas uma tarefa específica. Isso os torna uma entidade individual que é sustentável e testável . Serviços usados ​​para injetar usando o mecanismo de Injeção de Dependência do Angularjs.

Código angularjs:

app.service('communicate',function(){
  this.communicateValue='Hello';
});

app.controller('ParentCtrl',function(communicate){//Dependency Injection
  console.log(communicate.communicateValue+" Parent World");
});

app.controller('ChildCtrl',function(communicate){//Dependency Injection
  console.log(communicate.communicateValue+" Child World");
});

Vai dar saída Hello Child World e Hello Parent World. De acordo com o Angular docs of services Singletons - Cada componente dependente de um serviço obtém uma referência à instância única gerada pela fábrica de serviços .

4.Kind de hack - com a ajuda de angular.element ()

Este método obtém scope () do elemento por seu método id / unique class.angular.element () retorna elemento e escopo () dá $ variável de escopo de outra variável usando $ escopo variável de um controlador dentro de outro não é uma boa prática.

HTML: -

<div id='parent' ng-controller='ParentCtrl'>{{varParent}}
 <span ng-click='getValueFromChild()'>Click to get ValueFormChild</span>
 <div id='child' ng-controller='childCtrl'>{{varChild}}
   <span ng-click='getValueFromParent()'>Click to get ValueFormParent </span>
 </div>
</div>

Angularjs: -

app.controller('ParentCtrl',function($scope){
 $scope.varParent="Hello Parent";
  $scope.getValueFromChild=function(){
  var childScope=angular.element('#child').scope();
  console.log(childScope.varChild);
  }
});

app.controller('ChildCtrl',function($scope){
 $scope.varChild="Hello Child";
  $scope.getValueFromParent=function(){
  var parentScope=angular.element('#parent').scope();
  console.log(parentScope.varParent);
  }
}); 

Nos códigos acima, os controladores mostram seu próprio valor em Html e, quando você clica no texto, recebe valores no console. Se você clicar em span dos controladores pai, o navegador consolará o valor de child e vice-versa.


Veja este violino: http://jsfiddle.net/simpulton/XqDxG/

Veja também o seguinte vídeo: Comunicando entre controladores

Html:

<div ng-controller="ControllerZero">
  <input ng-model="message" >
  <button ng-click="handleClick(message);">LOG</button>
</div>

<div ng-controller="ControllerOne">
  <input ng-model="message" >
</div>

<div ng-controller="ControllerTwo">
  <input ng-model="message" >
</div>

javascript:

var myModule = angular.module('myModule', []);
myModule.factory('mySharedService', function($rootScope) {
  var sharedService = {};

  sharedService.message = '';

  sharedService.prepForBroadcast = function(msg) {
    this.message = msg;
    this.broadcastItem();
  };

  sharedService.broadcastItem = function() {
    $rootScope.$broadcast('handleBroadcast');
  };

  return sharedService;
});

function ControllerZero($scope, sharedService) {
  $scope.handleClick = function(msg) {
    sharedService.prepForBroadcast(msg);
  };

  $scope.$on('handleBroadcast', function() {
    $scope.message = sharedService.message;
  });        
}

function ControllerOne($scope, sharedService) {
  $scope.$on('handleBroadcast', function() {
    $scope.message = 'ONE: ' + sharedService.message;
  });        
}

function ControllerTwo($scope, sharedService) {
  $scope.$on('handleBroadcast', function() {
    $scope.message = 'TWO: ' + sharedService.message;
  });
}

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

ControllerOne.$inject = ['$scope', 'mySharedService'];

ControllerTwo.$inject = ['$scope', 'mySharedService'];

Se você estiver procurando emitir e transmitir eventos para compartilhar dados ou chamar funções entre controladores , por favor, olhe este link : e verifique a resposta por zbynour (responda com o máximo de votos). Estou citando sua resposta !!!

Se o escopo de firstCtrl é pai do escopo secondCtrl, seu código deve funcionar substituindo $ emit por $ broadcast em firstCtrl:

function firstCtrl($scope){
    $scope.$broadcast('someEvent', [1,2,3]);
}

function secondCtrl($scope){
    $scope.$on('someEvent', function(event, mass) {console.log(mass)});
}

Caso não haja uma relação pai-filho entre seus escopos, você pode injetar $ rootScope no controlador e transmitir o evento para todos os escopos filho (isto é, também segundoCtrl).

function firstCtrl($rootScope){
    $rootScope.$broadcast('someEvent', [1,2,3]);
}

Finalmente, quando você precisar despachar o evento do controlador filho para os escopos, poderá usar $ scope. $ Emit. Se o escopo de firstCtrl for pai do escopo secondCtrl:

function firstCtrl($scope){
    $scope.$on('someEvent', function(event, data) { console.log(data); });
}

function secondCtrl($scope){
    $scope.$emit('someEvent', [1,2,3]);
}




angularjs