[javascript] 한 AngularJS 컨트롤러가 다른 AngularJS 컨트롤러를 호출 할 수 있습니까?

한 컨트롤러가 다른 컨트롤러를 사용할 수 있습니까?

예를 들면 다음과 같습니다.

이 HTML 문서는 단순히 MessageCtrl컨트롤러가 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>

컨트롤러 파일에는 다음 코드가 포함되어 있습니다.

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

단순히 현재 날짜를 인쇄합니다.

DateCtrl특정 형식의 날짜를 다시 제출 한 다른 컨트롤러를 추가 하려면 MessageCtrl어떻게해야합니까? DI 프레임 워크는 XmlHttpRequests서비스에 액세스하고 액세스 하는 것으로 보입니다 .



답변

컨트롤러 간 통신 방법에는 여러 가지가 있습니다.

가장 좋은 것은 아마도 서비스를 공유하는 것입니다.

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
}

다른 방법은 범위에서 이벤트를 내보내는 것입니다.

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

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

두 경우 모두 지시어와도 통신 할 수 있습니다.


답변

이 바이올린을보십시오 : http://jsfiddle.net/simpulton/XqDxG/

다음 비디오도 시청하십시오. 컨트롤러 간 통신

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>

자바 스크립트 :

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'];


답변

하나의 컨트롤러를 다른 컨트롤러로 호출하려면 사용할 수있는 네 가지 방법이 있습니다

  1. $ rootScope. $ emit () 및 $ rootScope. $ broadcast ()
  2. 보조 컨트롤러가 자식 인 경우 부모 자식 통신을 사용할 수 있습니다.
  3. 서비스 이용
  4. 해킹의 종류-angular.element ()의 도움으로

1. $ rootScope. $ emit () 및 $ rootScope. $ broadcast ()

컨트롤러와 해당 범위는 손상 될 수 있지만 $ rootScope는 애플리케이션 전체에 남아 있으므로 $ rootScope는 모든 범위의 상위이므로 $ rootScope를 사용합니다.

부모와 자녀 사이에 의사 소통을하고 있고 심지어 자녀가 형제와 의사 소통하기를 원한다면 $ broadcast를 사용할 수 있습니다

자식에서 부모로의 통신을 수행하는 경우 형제가 없습니다. $ rootScope를 사용할 수 있습니다.

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>

Angularjs 코드

 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');
  });
});

위의 $ emit ‘childEmit’코드 콘솔에서는 자식 형제 내부를 호출하지 않으며 부모 내부에서만 호출합니다. 여기서 부모는 $ broadcast가 형제 및 부모 내부에서도 호출됩니다. 이것은 성능이 작동하는 곳입니다. 더티 검사를 건너 뛰기 때문에 자녀 간 통신을 사용하는 경우 선호됩니다.

2. 보조 컨트롤러가 하위 인 경우 하위 부모 커뮤니케이션을 사용할 수 있습니다

가장 좋은 방법 중 하나입니다 . 자녀가 직계 부모 와 의사 소통하기를 원하는 자녀 부모 의사 소통을 원한다면 어떤 종류의 $ broadcast 또는 $ emit이 필요하지 않지만 부모와 자녀 사이의 의사 소통을 원한다면 service 또는 $ broadcast를 사용하십시오

예를 들어 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);
  });

Child to Parent 통신을 사용할 때마다 Angularjs는 Child 내부의 변수를 검색합니다. 내부에 존재하지 않으면 상위 컨트롤러 내부의 값을 보도록 선택합니다.

3. 서비스 이용

AngularJS는 서비스 아키텍처를 사용하여 “문제의 분리” 개념을 지원합니다 . 서비스는 자바 스크립트 기능이며 특정 작업 만 수행 할 책임이 있습니다. 따라서 서비스는 유지 관리 및 테스트가 가능한 개별 엔티티 가 됩니다. Angularjs의 Dependency Injection mecahnism을 사용하여 주입하는 데 사용되는 서비스입니다.

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");
});

출력 Hello Child World 및 Hello Parent World가 출력됩니다. Angular 서비스 문서에 따르면 Singletons – 서비스에 종속 된 각 구성 요소는 서비스 팩토리에서 생성 된 단일 인스턴스에 대한 참조를 가져옵니다 .

해킹의 종류-angular.element ()의 도움으로

이 메소드는 Id / unique class.angular.element () 메소드로 요소에서 scope ()를 가져옵니다. element를 리턴하고 scope ()는 한 컨트롤러의 $ scope 변수를 사용하여 다른 변수의 $ scope 변수를 제공합니다.

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);
  }
}); 

위의 코드에서 컨트롤러는 Html에 자체 값을 표시하고 텍스트를 클릭하면 콘솔에 따라 값이 표시됩니다. 부모 컨트롤러 범위를 클릭하면 브라우저가 자식의 콘솔 값을 가져오고 그 반대도 마찬가지입니다.


답변

다음은 서비스 데이터를 공유하는 두 컨트롤러의 한 페이지 예입니다.

<!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>

또한 여기에 : https://gist.github.com/3595424


답변

컨트롤러간에 데이터를 공유하거나 기능을 호출하기 위해 이벤트를 내보내고 브로드 캐스트하려는 경우이 링크 를보고 답변을 확인하십시오 zbynour(최대 투표 수). 나는 그의 대답을 인용하고 있습니다 !!!

firstCtrl의 범위가 secondCtrl 범위의 부모 인 경우 코드는 firstCtrl에서 $ emit을 $ broadcast로 대체하여 작동합니다.

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

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

스코프간에 상위-하위 관계가없는 경우 $ rootScope를 컨트롤러에 주입하고 모든 하위 범위 (예 : secondCtrl)로 이벤트를 브로드 캐스트 할 수 있습니다.

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

마지막으로 자식 컨트롤러에서 범위를 넘어서 이벤트를 전달해야 할 경우 $ scope. $ emit을 사용할 수 있습니다. firstCtrl의 범위가 secondCtrl 범위의 상위 인 경우 :

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

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


답변

바이올린 두 개 더 : (비 서비스 방식)

1) $scope부모 -자식 컨트롤러의 경우- 부모 컨트롤러를 사용하여 이벤트를 발생 / 방송합니다.
http://jsfiddle.net/laan_sachin/jnj6y/

2) $rootScope관련이없는 컨트롤러에서 사용.
http://jsfiddle.net/VxafF/


답변

이벤트가 스코프 계층 구조를 위아래로 버블 링하여 복잡한 응용 프로그램의 성능 병목 상태로 쉽게 저하 될 수 있으므로 실제로 이미 터 및 브로드 캐스트를 사용하는 것은 비효율적입니다.

서비스를 사용하는 것이 좋습니다. – 저는 여기에 최근에 내 프로젝트 중 하나에 구현하는 방법이다 https://gist.github.com/3384419 .

기본 아이디어-펍 서브 / 이벤트 버스를 서비스로 등록하십시오. 그런 다음 이벤트 / 주제를 구독하거나 게시해야 할 경우 해당 이벤트 버스를 주입하십시오.