Bisakah satu pengontrol AngularJS memanggil yang lain?

581

Apakah mungkin untuk menggunakan satu pengontrol menggunakan yang lain?

Sebagai contoh:

Dokumen HTML ini hanya mencetak pesan yang dikirim oleh MessageCtrlpengontrol dalam messageCtrl.jsfile.

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

File pengontrol berisi kode berikut:

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

Yang hanya mencetak tanggal saat ini;

Jika saya menambahkan pengontrol lain, DateCtrlyang mengembalikan tanggal dalam format tertentu MessageCtrl, bagaimana cara melakukannya? Kerangka kerja DI tampaknya berkaitan dengan XmlHttpRequestsdan mengakses layanan.

BanksySan
sumber
4
Diskusi grup Google ini, groups.google.com/d/topic/angular/m_mn-8gnNt4/discussion , membahas 5 cara pengontrol dapat saling berbicara.
Mark Rajcok
Sudah ada jawaban yang bagus di sini, jadi saya hanya ingin menunjukkan bahwa untuk use case yang disebutkan, mungkin filter AngularJS akan menjadi solusi yang lebih baik? Hanya berpikir saya akan menyebutkannya :)
Joe Dyndale

Jawaban:

705

Ada beberapa cara bagaimana berkomunikasi antar pengendali.

Yang terbaik mungkin berbagi layanan:

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
}

Cara lain adalah memancarkan acara pada lingkup:

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

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

Dalam kedua kasus, Anda dapat berkomunikasi dengan arahan apa pun juga.

Vojta
sumber
4
Hia, Contoh pertama akan membutuhkan halaman web untuk mengetahui semua layanan di stack. Yang terasa seperti bau busuk (?). Seperti yang kedua, bukankah halaman web perlu memberikan argumen $ scope?
BanksySan
54
Apa? Mengapa? Semua pengontrol disuntikkan oleh DI Angular.
Vojta
7
@JoshNoe dalam 1 / Anda memiliki dua pengendali (atau lebih) dan keduanya mendapatkan satu layanan yang sama / dibagikan. Kemudian, Anda memiliki banyak cara bagaimana berkomunikasi, beberapa di antaranya Anda sebutkan. Saya akan memutuskan berdasarkan kasus penggunaan khusus Anda. Anda dapat menempatkan logika / status bersama ke dalam layanan dan kedua pengontrol hanya mendelegasikan layanan tersebut atau bahkan mengekspor layanan ke template. Tentu saja, layanan ini juga dapat memecat acara ...
Vojta
137
Datang ke ini selambat-lambatnya: kalian tahu Anda berdebat dengan THE Vojta dari Google yang bekerja di AngularJS, kan? :)
Suman
16
Tidak jelas bagi saya bahwa dalam HTML saya pengendali acara harus menjadi simpul anak-anak dari pengontrol mendengarkan agar berfungsi.
djangonaut
122

Lihat biola ini: http://jsfiddle.net/simpulton/XqDxG/

Tonton juga video berikut: Communicating Between Controllers

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'];
adardesign
sumber
12
Biola dan video berbagi layanan. Ini biola yang menggunakan $ scope. $ Emit
Mark Rajcok
1
@adardesign: Saya SENANG membaca contoh ringkas dan bermakna untuk arahan (terima kasih atas jawaban ini juga!)
sscarduzio
Jawaban Hebat, saya menggunakan myModule.service ('mySharedService', fungsi ($ rootScope) {}) alih-alih myModule.factory tetapi kerjanya tidak kurang!
TacoEater
Luar biasa. Meskipun, saya punya pertanyaan: Mengapa Anda menambahkan handler di dalam ControllerZero? $ scope. $ on ('handleBroadcast', function () {$ scope.message = sharedService.message;});
ZooZ
Video yang disediakan benar-benar luar biasa! Saya sepertinya inilah yang saya butuhkan untuk menanyakan keadaan pengontrol lain dari pengontrol lain. Namun, ini tidak berfungsi menggunakan fungsi "aktifkan". Ini bekerja menggunakan aksi "pemicu". Jadi secara efektif, jika pengontrol melakukan suatu tindakan, dan memiliki keadaan baru, maka, ia harus menyiarkan keadaan, dan terserah pengontrol lain untuk mendengarkan siaran itu dan merespons sesuai. Atau lebih baik, lakukan tindakan di layanan bersama, lalu siaran negara. Tolong beritahu saya jika pemahaman saya benar.
tarekahf
53

Jika Anda ingin memanggil satu pengontrol ke yang lain ada empat metode yang tersedia

  1. $ rootScope. $ emit () dan $ rootScope. $ broadcast ()
  2. Jika Kontroler kedua adalah anak, Anda dapat menggunakan komunikasi Anak Induk.
  3. Gunakan Layanan
  4. Jenis retasan - dengan bantuan angular.element ()

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

Kontroler dan cakupannya bisa dihancurkan, tetapi $ rootScope tetap ada di seluruh aplikasi, itu sebabnya kami mengambil $ rootScope karena $ rootScope adalah induk dari semua lingkup.

Jika Anda melakukan komunikasi dari orang tua ke anak dan bahkan anak ingin berkomunikasi dengan saudara kandungnya, Anda dapat menggunakan $ broadcast

Jika Anda melakukan komunikasi dari anak ke orang tua, tidak ada saudara yang terlibat maka Anda dapat menggunakan $ 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>

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

Dalam kode di atas konsol $ emit 'childEmit' tidak akan memanggil saudara dalam dan itu akan memanggil orangtua hanya di dalam, di mana $ broadcast dipanggil di dalam saudara dan orang tua juga. Ini adalah tempat di mana kinerja beraksi. $ Emit adalah lebih disukai, jika Anda menggunakan komunikasi anak ke orang tua karena itu melewatkan beberapa pemeriksaan kotor.

2. Jika pengontrol kedua adalah anak, Anda dapat menggunakan komunikasi Orangtua Anak

Ini salah satu metode terbaik, Jika Anda ingin melakukan komunikasi orang tua anak di mana anak ingin berkomunikasi dengan orang tua langsung maka itu tidak memerlukan $ broadcast atau $ emit tetapi jika Anda ingin melakukan komunikasi dari orang tua ke anak maka Anda harus baik menggunakan layanan atau $ broadcast

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

Setiap kali Anda menggunakan komunikasi child to parent, Angularjs akan mencari variabel inside child, Jika tidak ada di dalamnya maka ia akan memilih untuk melihat nilai-nilai di dalam pengontrol induk.

3.Gunakan Layanan

AngularJS mendukung konsep "Seperation of Concerns" menggunakan arsitektur layanan. Layanan adalah fungsi javascript dan bertanggung jawab untuk melakukan tugas tertentu saja. Ini menjadikannya entitas individu yang dapat dipelihara dan diuji. Layanan yang digunakan untuk menyuntikkan menggunakan Dependency Injection mecahnism dari Angularjs.

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

Ini akan memberikan output Hello Child World dan Hello Parent World. Menurut dokumen Angular dari layanan Singletons - Setiap komponen yang bergantung pada layanan mendapat referensi ke instance tunggal yang dihasilkan oleh pabrik layanan .

4.Jenis hack - dengan bantuan angular.element ()

Metode ini mendapatkan scope () dari elemen dengan metode Id / unique class.angular.element () mengembalikan elemen dan scope () memberikan variabel $ scope dari variabel lain menggunakan $ scope variable dari satu pengontrol di dalam pengontrol lain bukanlah praktik yang baik.

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

Dalam pengendali kode di atas menunjukkan nilai mereka sendiri pada Html dan ketika Anda akan mengklik teks Anda akan mendapatkan nilai-nilai di konsol yang sesuai. Jika Anda mengklik rentang pengendali induk, browser akan menghibur nilai anak dan sebaliknya.

Shubham Nigam
sumber
52

Berikut adalah contoh satu halaman dari dua pengontrol yang membagikan data layanan:

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

Juga di sini: https://gist.github.com/3595424

exclsr
sumber
Dan jika theServiceupdate thing.x, maka bahwa perubahan otomatis propageates ke <input> s di FirstCtrldan SecondCtrl, kan? Dan seseorang juga dapat mengubah thing.xsecara langsung melalui salah satu dari dua <input> (kan?).
KajMagnus
4
Iya. Semua layanan Angular adalah lajang aplikasi, yang berarti hanya ada satu contoh Layanan. Referensi: docs.angularjs.org/guide/dev_guide.services.creating_services
exclsr
Tautan dalam komentar saya sebelumnya adalah 404, jadi di sini adalah panduan layanan, hari ini, yang mencatat layanan adalah lajang: docs.angularjs.org/guide/services
exclsr
1
@exclsr Ya! Maaf saya melewatkan itu sebelumnya
CodyBugstein
3
Sejauh ini contoh terbaik yang pernah saya lihat di web sejauh ini. Terima kasih
Sevenearths
33

Jika Anda ingin memancarkan & menyiarkan acara untuk berbagi data atau fungsi panggilan di seluruh pengontrol , silakan lihat tautan ini : dan periksa jawabannya dengan zbynour(menjawab dengan suara maksimal). Saya mengutip jawabannya !!!

Jika ruang lingkup firstCtrl adalah induk dari ruang lingkup secondCtrl, kode Anda harus bekerja dengan mengganti $ emit dengan $ broadcast di firstCtrl:

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

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

Jika tidak ada hubungan orangtua-anak di antara cakupan Anda, Anda bisa menyuntikkan $ rootScope ke controller dan menyiarkan acara ke semua cakupan anak (yaitu juga secondCtrl).

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

Akhirnya, ketika Anda perlu mengirim acara dari child controller ke cakupan Anda dapat menggunakan $ scope. $ Emit Jika cakupan firstCtrl adalah induk dari lingkup secondCtrl:

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

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

Dua biola lagi: (Pendekatan non-layanan)

1) Untuk Pengontrol Orangtua-Anak - Menggunakan $scopepengontrol induk untuk memancarkan / menyiarkan acara. http://jsfiddle.net/laan_sachin/jnj6y/

2) Menggunakan $rootScopeseluruh pengontrol yang tidak terkait. http://jsfiddle.net/VxafF/

Kesatria Kegelapan
sumber
Apa alasan untuk semua kerumitan ini dengan peristiwa? Kenapa tidak melakukan hal seperti ini? jsfiddle.net/jnj6y/32
Dfr
Itu tergantung pada hubungan orangtua seperti apa yang benar. Mungkin itu adalah warisan DOM, jika peristiwa itu memungkinkan Anda untuk memisahkan hal-hal.
DarkKnight
17

Sebenarnya menggunakan memancarkan dan menyiarkan tidak efisien karena peristiwa menggelembung naik dan turunnya hierarki ruang lingkup yang dapat dengan mudah menurunkan ke kinerja bottlement untuk aplikasi yang kompleks.

Saya akan menyarankan menggunakan layanan. Inilah cara saya baru-baru ini mengimplementasikannya di salah satu proyek saya - https://gist.github.com/3384419 .

Ide dasar - daftarkan bus pub-sub / acara sebagai layanan. Kemudian menyuntikkan bus acara itu di mana pun Anda perlu berlangganan atau mempublikasikan acara / topik.

salati numan
sumber
5

Saya juga tahu cara ini.

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

Tapi saya tidak menggunakannya terlalu banyak, karena saya tidak suka menggunakan pemilih jQuery dalam kode sudut.

Andrey Korchak
sumber
jawaban terbaik Sangat sederhana dan mudah ... =)
zVictor
3
@Victor, ini benar-benar tipe pendekatan "pilihan terakhir". Ini bekerja, tetapi itu keluar dari ruang lingkup untuk memaksa jalan Anda kembali. Ini menggunakan manipulasi DOM untuk memaksa sesuatu yang harus dilakukan alih-alih secara terprogram melakukannya. Sederhana, ini berfungsi, tetapi tidak bisa diukur.
Brian Noah
2
@BrianNoah, benar. Tidak masalah menggunakan kode ini untuk prototipe atau eksperimen, tetapi tidak untuk kode produksi.
Andrey Korchak
1
Itu hal terburuk yang bisa dilakukan. Manipulasi DOM dalam layanan dan akses ruang lingkup langsung.
Mattia Franchetto
3

Ada metode yang tidak tergantung pada layanan, $broadcastatau $emit. Ini tidak cocok dalam semua kasus, tetapi jika Anda memiliki 2 pengontrol terkait yang dapat diabstraksikan menjadi arahan, maka Anda dapat menggunakan requireopsi dalam definisi arahan. Ini kemungkinan besar bagaimana ngModel dan ngForm berkomunikasi. Anda bisa menggunakan ini untuk berkomunikasi antara pengontrol direktif yang bersarang, atau pada elemen yang sama.

Untuk situasi orang tua / anak, penggunaannya adalah sebagai berikut:

<div parent-directive>
  <div inner-directive></div>
</div>

Dan poin utama untuk membuatnya bekerja: Pada arahan induk, dengan metode yang akan dipanggil, Anda harus mendefinisikannya this(bukan pada$scope ):

controller: function($scope) {
  this.publicMethodOnParentDirective = function() {
    // Do something
  }
}

Pada definisi arahan anak, Anda dapat menggunakan requireopsi sehingga pengontrol induk diteruskan ke fungsi tautan (sehingga Anda dapat memanggil fungsi di dalamnya dariscope arahan anak.

require: '^parentDirective',
template: '<span ng-click="onClick()">Click on this to call parent directive</span>',
link: function link(scope, iElement, iAttrs, parentController) {
  scope.onClick = function() {
    parentController.publicMethodOnParentDirective();
  }
}

Di atas dapat dilihat di http://plnkr.co/edit/poeq460VmQER8Gl9w8Oz?p=preview

Arahan saudara digunakan sama, tetapi kedua arahan pada elemen yang sama:

<div directive1 directive2>
</div>

Digunakan dengan membuat metode pada directive1:

controller: function($scope) {
  this.publicMethod = function() {
    // Do something
  }
}

Dan dalam directive2 ini dapat dipanggil dengan menggunakan requireopsi yang menghasilkan siblingController diteruskan ke fungsi tautan:

require: 'directive1',
template: '<span ng-click="onClick()">Click on this to call sibling directive1</span>',
link: function link(scope, iElement, iAttrs, siblingController) {
  scope.onClick = function() {
    siblingController.publicMethod();
  }
}

Ini bisa dilihat di http://plnkr.co/edit/MUD2snf9zvadfnDXq85w?p=preview .

Penggunaan ini?

  • Induk: Setiap kasus di mana elemen anak perlu "mendaftar" sendiri dengan orangtua. Sama seperti hubungan antara ngModel dan ngForm. Ini dapat menambahkan perilaku tertentu yang dapat memengaruhi model. Anda mungkin memiliki sesuatu yang murni berdasarkan DOM, di mana elemen induk perlu mengelola posisi anak-anak tertentu, misalnya mengelola atau bereaksi terhadap pengguliran.

  • Sibling: memungkinkan arahan untuk mengubah perilakunya. ngModel adalah kasus klasik, untuk menambahkan parser / validasi ke ngModel digunakan pada input.

Michal Charemza
sumber
3

Saya tidak tahu apakah ini di luar standar tetapi jika Anda memiliki semua pengontrol Anda pada file yang sama, maka Anda dapat melakukan sesuatu seperti ini:

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() {...}
}]);

Seperti yang Anda lihat indikatorCtrl memanggil fungsi updateChart dari kedua pengendali lainnya saat memanggil updateCharts.

tomascharad
sumber
2

Anda dapat menyuntikkan layanan '$ controller' di controller induk Anda (MessageCtrl) dan kemudian instantiate / inject child controller (DateCtrl) menggunakan:
$scope.childController = $controller('childController', { $scope: $scope.$new() });

Sekarang Anda dapat mengakses data dari pengontrol anak Anda dengan memanggil metodenya karena ini adalah layanan.
Beri tahu saya jika ada masalah.

Smrutiranjan Sahu
sumber
1

Berikut ini adalah a publish-subscribe pendekatan yang terlepas dari JS Angular.

Cari Param Controller

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

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

Kontrol Pilihan Pencarian

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


});

Pengelola acara

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;
LCJ
sumber
1

Dalam sudut 1,5 ini dapat dilakukan dengan melakukan hal berikut:

(function() {
  'use strict';

  angular
    .module('app')
    .component('parentComponent',{
      bindings: {},
      templateUrl: '/templates/products/product.html',
      controller: 'ProductCtrl as vm'
    });

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

  function ProductCtrl() {
    var vm = this;
    vm.openAccordion = false;

    // Capture stuff from each of the product forms
    vm.productForms = [{}];

    vm.addNewForm = function() {
      vm.productForms.push({});
    }
  }

}());

Ini adalah komponen induk. Dalam hal ini saya telah membuat sebuah fungsi yang mendorong objek lain ke dalam productFormsarray saya - note - ini hanya contoh saya, fungsi ini bisa apa saja.

Sekarang kita dapat membuat komponen lain yang akan menggunakan require:

(function() {
  'use strict';

  angular
    .module('app')
    .component('childComponent', {
      bindings: {},
      require: {
        parent: '^parentComponent'
      },
      templateUrl: '/templates/products/product-form.html',
      controller: 'ProductFormCtrl as vm'
    });

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

  function ProductFormCtrl() {
    var vm = this;

    // Initialization - make use of the parent controllers function
    vm.$onInit = function() {
      vm.addNewForm = vm.parent.addNewForm;
    };  
  }

}());

Di sini komponen anak membuat referensi ke fungsi komponen orang tua addNewFormyang kemudian dapat diikat ke HTML dan dipanggil seperti fungsi lainnya.

Katana24
sumber