javascript angularjs شرح - العمل مع نطاق $. $ emit و $ scope. $ on
وأود أن أقترح بالإضافة إلى ذلك خيار رابع كبديل أفضل للخيارات المقترحة بواسطةzbynour.
استخدم $rootScope.$emit
بدلاً من $rootScope.$broadcast
بغض النظر عن العلاقة بين trasitting وجهاز الاستقبال المتلقي. وبهذه الطريقة ، يظل الحدث ضمن مجموعة $rootScope.$$listeners
بينما في $rootScope.$broadcast
الحدث إلى جميع نطاقات الأطفال ، وربما لن يكون معظمهم مستمعين لهذا الحدث على أي حال. وبطبيعة الحال في نهاية وحدة تحكم المتلقي عليك فقط استخدام $rootScope.$on
.
لهذا الخيار يجب أن تتذكر أن تدمر المستمعين rootScope وحدة التحكم:
var unbindEventHandler = $rootScope.$on('myEvent', myHandler);
$scope.$on('$destroy', function () {
unbindEventHandler();
});
كيف يمكنني إرسال كائن $scope
بي من جهاز تحكم إلى آخر باستخدام .$emit
و .$on
function firstCtrl($scope) {
$scope.$emit('someEvent', [1,2,3]);
}
function secondCtrl($scope) {
$scope.$on('someEvent', function(mass) { console.log(mass); });
}
لا يعمل بالطريقة التي أعتقد أنها يجب أن تكون. كيف $emit
$on
و $on
العمل؟
لإرسال $scope object
من وحدة تحكم إلى أخرى ، سأناقش حول $rootScope.$broadcast
و $rootScope.$emit
هنا حيث يتم استخدامها أكثر من غيرها.
الحالة 1 :
$ $ rootScope البث: -
$rootScope.$broadcast('myEvent',$scope.data);//Here `myEvent` is event name
$rootScope.$on('myEvent', function(event, data) {} //listener on `myEvent` event
$rootScope
لم يتم إتلاف المستمع تلقائيا. تحتاج إلى تدميرها باستخدام $destroy
. من الأفضل استخدام $scope.$on
يتم إتلاف $scope
كمستمعين على $scope
تلقائيًا ، أي بمجرد تدمير نطاق $.
$scope.$on('myEvent', function(event, data) {}
أو،
var customeEventListener = $rootScope.$on('myEvent', function(event, data) {
}
$scope.$on('$destroy', function() {
customeEventListener();
});
الحالة 2:
. $ $ rootScope تنبعث منها:
$rootScope.$emit('myEvent',$scope.data);
$rootScope.$on('myEvent', function(event, data) {}//$scope.$on not works
الاختلاف الرئيسي في $ emit و $ broadcast هو أنه يجب أن يتم الإصغاء $ rootcope. $ emit event باستخدام $ rootScope. $ on ، لأن الحدث الذي تم إرساله لا ينزل من خلال شجرة النطاق. .
في هذه الحالة أيضا يجب عليك تدمير المستمع كما هو الحال في حالة البث $.
تصحيح:
أفضل عدم استخدام
$rootScope.$broadcast + $scope.$on
but use$rootScope.$emit+ $rootScope.$on
. يمكن أن$rootScope.$broadcast + $scope.$on
التحرير والسرد في حدوث مشكلات خطيرة في الأداء. هذا لأن الحدث سوف يتدفق من خلال جميع النطاقات.
تحرير 2 :
تم حل المشكلة التي تم تناولها في هذه الإجابة في الإصدار 1.2.7 من angular.js. يتجنب البث $ الآن حدوث فقاعات عبر نطاقات غير مسجلة ، ويتم تشغيله بالسرعة نفسها التي ينبعث منها الدولار.
يمكنك استدعاء خدمة من وحدة التحكم الخاصة بك التي تعيد الوعد ثم استخدامها في وحدة التحكم الخاصة بك. وكذلك استخدام $emit
أو $broadcast
لإعلام وحدات التحكم الأخرى حول هذا الموضوع. في حالتي ، اضطررت إلى إجراء مكالمات http من خلال الخدمة ، لذا فعلت شيئًا كهذا:
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
})
}
و خدمتي تبدو هكذا
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);
});
}
}])
<!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>
يعرض رمز أدناه اثنين من وحدات تحكم فرعية من حيث يتم إرسال الأحداث صعودا إلى وحدة تحكم الأصل (rootScope)
<body ng-app="App">
<div ng-controller="parentCtrl">
<p>City : {{city}} </p>
<p> Address : {{address}} </p>
<div ng-controller="subCtrlOne">
<input type="text" ng-model="city" />
<button ng-click="getCity(city)">City !!!</button>
</div>
<div ng-controller="subCtrlTwo">
<input type="text" ng-model="address" />
<button ng-click="getAddrress(address)">Address !!!</button>
</div>
</div>
</body>
var App = angular.module('App', []);
// parent controller
App.controller('parentCtrl', parentCtrl);
parentCtrl.$inject = ["$scope"];
function parentCtrl($scope) {
$scope.$on('cityBoom', function(events, data) {
$scope.city = data;
});
$scope.$on('addrBoom', function(events, data) {
$scope.address = data;
});
}
// sub controller one
App.controller('subCtrlOne', subCtrlOne);
subCtrlOne.$inject = ['$scope'];
function subCtrlOne($scope) {
$scope.getCity = function(city) {
$scope.$emit('cityBoom', city);
}
}
// sub controller two
App.controller('subCtrlTwo', subCtrlTwo);
subCtrlTwo.$inject = ["$scope"];
function subCtrlTwo($scope) {
$scope.getAddrress = function(addr) {
$scope.$emit('addrBoom', addr);
}
}
http://jsfiddle.net/shushanthp/zp6v0rut/
وفقاً لمستندات أحداث angularjs ، يجب أن يحتوي طرف المتلقي على وسائط ذات بنية مثل
params
- يكون حدث {الكائن} كائن الحدث الذي يحتوي على معلومات حول الحدث
- {object} args التي يتم تمريرها بواسطة المستدعي (لاحظ أن هذا يمكن أن يكون واحدًا أفضل لإرساله في كائن القاموس دائمًا)
$scope.$on('fooEvent', function (event, args) { console.log(args) });
من الكود الخاص بك
أيضا إذا كنت تحاول الحصول على جزء من المعلومات المشتركة المتاحة عبر وحدات تحكم مختلفة ، فهناك طريقة أخرى لتحقيق ذلك ، وهي خدمات زاوية.لأنه يمكن تخزين المعلومات الفردية وجمعها عبر أجهزة التحكم. وظائف الضبط في هذه الخدمة ، وفضح هذه الوظائف ، وجعل المتغيرات العالمية في الخدمة واستخدامها لتخزين المعلومات