Pertanyaan Bekerja dengan $ scope, $ emit, dan $ scope. $ On


Bagaimana saya bisa mengirim saya $scope objek dari satu pengontrol ke yang lain menggunakan .$emit dan .$on metode?

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

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

Itu tidak bekerja menurut saya seharusnya. Bagaimana $emit dan $on kerja?


844
2018-01-24 13:03


asal


Jawaban:


Pertama-tama, hubungan ruang lingkup orang tua-anak memang penting. Anda memiliki dua kemungkinan untuk memancarkan beberapa acara:

  • $broadcast - mengirimkan acara ke bawah ke semua cakupan anak,
  • $emit - mengirimkan acara ke atas melalui hierarki lingkup.

Saya tidak tahu apa-apa tentang hubungan pengontrol (cakupan) Anda, tetapi ada beberapa opsi:

  1. Jika ruang lingkup firstCtrl adalah induk dari secondCtrl ruang lingkup, kode Anda seharusnya bekerja dengan mengganti $emit oleh $broadcast di firstCtrl:

    function firstCtrl($scope)
    {
        $scope.$broadcast('someEvent', [1,2,3]);
    }
    
    function secondCtrl($scope)
    {
        $scope.$on('someEvent', function(event, mass) { console.log(mass); });
    }
    
  2. Dalam hal tidak ada hubungan orangtua-anak antara lingkup Anda Anda bisa menyuntikkan $rootScope ke pengontrol dan menyiarkan acara ke semua lingkup anak (yaitu juga secondCtrl).

    function firstCtrl($rootScope)
    {
        $rootScope.$broadcast('someEvent', [1,2,3]);
    }
    
  3. Akhirnya, ketika Anda perlu mengirimkan acara dari pengendali anak untuk lingkup ke atas yang dapat Anda gunakan $scope.$emit. Jika ruang lingkup firstCtrl adalah induk dari secondCtrl cakupan:

    function firstCtrl($scope)
    {
        $scope.$on('someEvent', function(event, data) { console.log(data); });
    }
    
    function secondCtrl($scope)
    {
        $scope.$emit('someEvent', [1,2,3]);
    }
    

1465
2018-01-24 13:41



Saya juga menyarankan opsi keempat sebagai alternatif yang lebih baik untuk opsi yang diusulkan oleh @zbynour.

Menggunakan $rootScope.$emit daripada $rootScope.$broadcast terlepas dari hubungan antara trasmitting dan menerima controller. Dengan begitu, acara tetap berada di dalam set $rootScope.$$listeners sedangkan dengan $rootScope.$broadcast acara ini menyebar ke semua lingkup anak-anak, yang sebagian besar mungkin bukan pendengar acara itu. Dan tentu saja di ujung pengontrol penerima yang baru saja Anda gunakan $rootScope.$on.

Untuk opsi ini Anda harus ingat untuk menghancurkan pendengar rootScope pengendali:

var unbindEventHandler = $rootScope.$on('myEvent', myHandler);
$scope.$on('$destroy', function () {
  unbindEventHandler();
});

140
2018-04-06 19:34



Bagaimana saya bisa mengirim objek $ scope saya dari satu controller ke yang lain menggunakan metode $ emit dan. $ On?

Anda dapat mengirim objek apa pun yang Anda inginkan dalam hierarki aplikasi Anda, termasuk $ scope.

Berikut ini ide singkat tentang bagaimana siaran dan memancarkan kerja.

Perhatikan node di bawah ini; semua bersarang di dalam node 3. Anda menggunakan siaran dan memancarkan ketika Anda memiliki skenario ini.

catatan: Jumlah setiap node dalam contoh ini adalah arbitrary; itu bisa dengan mudah menjadi nomor satu; nomor dua; atau bahkan angka 1.348. Setiap angka hanyalah sebuah identifier untuk contoh ini. Inti dari contoh ini adalah untuk menunjukkan bersarangnya pengendali / arahan Sudut.

                 3
           ------------
           |          |
         -----     ------
         1   |     2    |
      ---   ---   ---  ---
      | |   | |   | |  | |

Lihat pohon ini. Bagaimana Anda menjawab pertanyaan-pertanyaan berikut?

catatan: Ada cara lain untuk menjawab pertanyaan-pertanyaan ini, tetapi di sini kita akan membahas siaran dan memancarkan. Juga, ketika membaca teks di bawah ini menganggap setiap angka memiliki file itu sendiri (direktif, pengontrol) e.x. one.js, two.js, three.js.

Bagaimana simpulnya 1 berbicara dengan node 3?

Dalam file one.js

scope.$emit('messageOne', someValue(s));

Dalam file three.js - node paling atas ke semua node anak yang diperlukan untuk berkomunikasi.

scope.$on('messageOne', someValue(s));

Bagaimana cara node 2 berbicara dengan node 3?

Dalam file two.js

scope.$emit('messageTwo', someValue(s));

Dalam file three.js - node paling atas ke semua node anak yang diperlukan untuk berkomunikasi.

scope.$on('messageTwo', someValue(s));

Bagaimana cara node 3 berbicara dengan node 1 dan / atau node 2?

Dalam file three.js - node paling atas ke semua node anak yang diperlukan untuk berkomunikasi.

scope.$broadcast('messageThree', someValue(s));

Dalam file one.js && two.js file mana pun yang Anda ingin menangkap pesan atau keduanya.

scope.$on('messageThree', someValue(s));

Bagaimana cara simpul 2 berbicara dengan simpul 1?

Dalam file two.js

scope.$emit('messageTwo', someValue(s));

Dalam file three.js - node paling atas ke semua node anak yang diperlukan untuk berkomunikasi.

scope.$on('messageTwo', function( event, data ){
  scope.$broadcast( 'messageTwo', data );
});

Dalam file one.js

scope.$on('messageTwo', someValue(s));

NAMUN

Bila Anda memiliki node anak-anak bertingkat yang mencoba berkomunikasi seperti ini, Anda akan segera melihat banyak $ on, $ broadcast, dan $ emit.

Inilah yang saya suka lakukan.

Dalam NAMA ORANG TERTINGGI ( 3 dalam hal ini ...), yang mungkin adalah pengendali orang tua Anda ...

Jadi, dalam file three.js

scope.$on('pushChangesToAllNodes', function( event, message ){
  scope.$broadcast( message.name, message.data );
});

Sekarang di salah satu node anak Anda hanya perlu $ emit pesan atau menangkapnya menggunakan $ pada.

CATATAN: Biasanya cukup mudah untuk berbicara silang dalam satu jalur bersarang tanpa menggunakan $ emit, $ broadcast, atau $ pada, yang berarti kebanyakan kasus penggunaan adalah ketika Anda mencoba mendapatkan node 1 untuk berkomunikasi dengan node 2 atau sebaliknya.

Bagaimana cara simpul 2 berbicara dengan simpul 1?

Dalam file two.js

scope.$emit('pushChangesToAllNodes', sendNewChanges());

function sendNewChanges(){ // for some event.
  return { name: 'talkToOne', data: [1,2,3] };
}

Dalam file three.js - node paling atas ke semua node anak yang diperlukan untuk berkomunikasi.

Kami sudah menangani yang satu ini, ingat?

Dalam file one.js

scope.$on('talkToOne', function( event, arrayOfNumbers ){
  arrayOfNumbers.forEach(function(number){
    console.log(number);
  });
});

Anda masih perlu menggunakan $ pada dengan setiap nilai spesifik yang ingin Anda tangkap, tetapi sekarang Anda dapat membuat apa pun yang Anda suka di node mana pun tanpa harus khawatir tentang cara mendapatkan pesan di celah node induk saat kami menangkap dan menyiarkan generik pushChangesToAllNodes.

Semoga ini membantu...


107
2017-07-11 14:47



Mengirim $scope object dari satu controller ke yang lain, saya akan membahas tentang $rootScope.$broadcast dan $rootScope.$emit di sini karena mereka paling banyak digunakan.

Kasus 1:

$ rootScope. $ broadcast: -

$rootScope.$broadcast('myEvent',$scope.data);//Here `myEvent` is event name

$rootScope.$on('myEvent', function(event, data) {} //listener on `myEvent` event

$rootScope pendengar tidak dihancurkan secara otomatis. Anda perlu menghancurkannya menggunakan $destroy. Lebih baik digunakan $scope.$on sebagai pendengar $scope dimusnahkan secara otomatis yaitu segera setelah $ scope dihancurkan.

$scope.$on('myEvent', function(event, data) {}

Atau,

  var customeEventListener = $rootScope.$on('myEvent', function(event, data) {

  }
  $scope.$on('$destroy', function() {
        customeEventListener();
  });

Kasus 2: 

$ rootScope. $ emit:

   $rootScope.$emit('myEvent',$scope.data);

   $rootScope.$on('myEvent', function(event, data) {}//$scope.$on not works

Perbedaan utama dalam $ emit dan $ broadcast adalah $ rootScope. $ Emit event harus didengarkan menggunakan $ rootScope. $ On, karena peristiwa yang dipancarkan tidak pernah turun melalui scope tree..
Dalam hal ini juga Anda harus menghancurkan pendengar seperti dalam kasus $ broadcast.

Edit:

Saya lebih suka tidak menggunakan $rootScope.$broadcast + $scope.$on tapi gunakan    $rootScope.$emit+ $rootScope.$on. Itu $rootScope.$broadcast + $scope.$on combo dapat menyebabkan masalah kinerja yang serius. Itu adalah   karena acara akan menggelembung melalui semua cakupan.

Edit 2:

Masalah yang dibahas dalam jawaban ini telah diselesaikan dalam angular.js   versi 1.2.7. $ broadcast sekarang menghindarkan diri dari ruang lingkup yang tidak terdaftar   dan berjalan secepat $ emit.


35
2018-04-02 18:54



Anda harus menggunakan $ rootScope untuk mengirim dan menangkap peristiwa antar kontroler dalam aplikasi yang sama. Sisipkan dependensi $ rootScope ke pengontrol Anda. Berikut ini contoh kerja.

app.controller('firstCtrl', function($scope, $rootScope) {        
        function firstCtrl($scope) {
        {
            $rootScope.$emit('someEvent', [1,2,3]);
        }
}

app.controller('secondCtrl', function($scope, $rootScope) {
        function secondCtrl($scope)
        {
            $rootScope.$on('someEvent', function(event, data) { console.log(data); });
        }
}

Acara yang ditautkan ke objek $ scope hanya berfungsi di pengontrol pemilik. Komunikasi antar kontroler dilakukan melalui $ rootScope atau Layanan.


10
2018-01-10 07:01



Anda dapat memanggil layanan dari pengontrol yang mengembalikan janji dan kemudian menggunakannya di pengontrol Anda. Dan selanjutnya digunakan $emit atau $broadcast untuk menginformasikan pengendali lain tentang hal itu. Dalam kasus saya, saya harus melakukan panggilan http melalui layanan saya, jadi saya melakukan sesuatu seperti ini:

function ParentController($scope, testService) {
    testService.getList()
        .then(function(data) {
            $scope.list = testService.list;
        })
        .finally(function() {
            $scope.$emit('listFetched');
        })


    function ChildController($scope, testService) {
        $scope.$on('listFetched', function(event, data) {
            // use the data accordingly
        })
    }

dan layanan saya terlihat seperti ini

    app.service('testService', ['$http', function($http) {

        this.list = [];

        this.getList = function() {
            return $http.get(someUrl)
                .then(function(response) {
                    if (typeof response.data === 'object') {
                        list = response.data.results;

                        return response.data;
                    } else {
                        // invalid response
                        return $q.reject(response.data);
                    }

                }, function(response) {
                    // something went wrong
                    return $q.reject(response.data);
                });

        }

    }])

6
2018-03-20 11:19



Ini adalah fungsi saya:

$rootScope.$emit('setTitle', newVal.full_name);

$rootScope.$on('setTitle', function(event, title) {
    if (scope.item) 
        scope.item.name = title;
    else 
        scope.item = {name: title};
});

3
2017-09-11 10:37



<!DOCTYPE html>
<html>

<head>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
var app = angular.module('MyApp',[]);
app.controller('parentCtrl',function($scope){
  $scope.$on('MyEvent',function(event,data){    
    $scope.myData = data;
  });
 });

app.controller('childCtrl',function($scope){
  $scope.fireEvent = function(){ 
  $scope.$emit('MyEvent','Any Data');
  }  
 });
</script>
</head>
<body ng-app="MyApp">
<div ng-controller="parentCtrl" ng-model="myName">

{{myData}}

 <div ng-controller="childCtrl">
   <button ng-click="fireEvent()">Fire Event</button>
 </div>

</div>
</body>
</html>

3
2018-04-13 13:25



Saya akhirnya menambahkan perpustakaan EventEmitter eksternal untuk memproyeksikan sebagai layanan dan menyuntikkannya di mana pun saya butuhkan. Jadi saya bisa "memancarkan" dan "pada" apa pun di mana saja tanpa memperhatikan lingkup pewarisan. Ini kurang masalah dengan cara ini dan tentu saja kinerja yang lebih baik. Juga lebih mudah dibaca oleh saya.

Dukungan wildcard: EventEmitter2

Penampilan yang bagus: eventemitter3

Alternatif lain: Menitik


2
2017-10-23 21:33