অ্যাঙ্গুলারজেএস-এ নিয়ন্ত্রণকারীদের মধ্যে যোগাযোগের সঠিক উপায় কী?


473

নিয়ন্ত্রণকারীদের মধ্যে যোগাযোগের সঠিক উপায় কী?

আমি বর্তমানে জড়িত একটি ভয়াবহ ফ্যাজ ব্যবহার করছি window:

function StockSubgroupCtrl($scope, $http) {
    $scope.subgroups = [];
    $scope.handleSubgroupsLoaded = function(data, status) {
        $scope.subgroups = data;
    }
    $scope.fetch = function(prod_grp) {
        $http.get('/api/stock/groups/' + prod_grp + '/subgroups/').success($scope.handleSubgroupsLoaded);
    }
    window.fetchStockSubgroups = $scope.fetch;
}

function StockGroupCtrl($scope, $http) {
    ...
    $scope.select = function(prod_grp) {
        $scope.selectedGroup = prod_grp;
        window.fetchStockSubgroups(prod_grp);
    }
}

36
সম্পূর্ণ মোটা, তবে কৌণিক ক্ষেত্রে আপনার সর্বদা নেটিভ জেএস উইন্ডো অবজেক্টের পরিবর্তে উইন্ডো ব্যবহার করা উচিত। এইভাবে আপনি এটি আপনার পরীক্ষাগুলিতে আটকে রাখতে পারেন :)
ড্যান এম

1
এই সমস্যাটি সম্পর্কে আমার কাছ থেকে নীচের উত্তরে মন্তব্যটি দেখুন। $ সম্প্রচার আর ইমিটের চেয়ে বেশি ব্যয়বহুল নয়। আমি সেখানে উল্লেখ করেছি jsperf লিঙ্কটি দেখুন।
জুমালাইফগার্ড

উত্তর:


457

সম্পাদনা : এই উত্তরে সম্বোধিত সমস্যাটি কৌণিক.জেএস সংস্করণ ১.২..7 এ সমাধান করা হয়েছে । $broadcastএখন নিবন্ধভুক্ত স্কোপগুলিতে বুদবুদ এড়ানো এবং এমিটের মতো দ্রুত চলে। $ সম্প্রচারের পারফরম্যান্সগুলি কৌণিক 1.2.16 এর সাথে নির্গত to

সুতরাং, এখন আপনি করতে পারেন:

  • $broadcastথেকে ব্যবহার করুন$rootScope
  • $on স্থানীয়দের কাছ থেকে$scope এই ইভেন্টটি সম্পর্কে জানা দরকার তা ব্যবহার করে শুনুন

নীচে মূল উত্তর

আমি উচ্চতর পরামর্শ দিচ্ছি $rootScope.$broadcast+ না $scope.$onবরং $rootScope.$emit+ ব্যবহার করুন $rootScope.$on। পূর্ববর্তী @numan দ্বারা উত্থাপিত হিসাবে গুরুতর পারফরম্যান্স সমস্যা সৃষ্টি করতে পারে। কারণ ইভেন্টটি সমস্ত স্কোপগুলিতে বুদবুদ হবে ।

তবে, আধুনিক (ব্যবহার $rootScope.$emit+ $rootScope.$on) এতে ভোগেন না এবং তাই দ্রুত যোগাযোগ চ্যানেল হিসাবে ব্যবহার করা যেতে পারে!

এর কৌনিক ডকুমেন্টেশন থেকে $emit:

রেজিস্টার্ডকে অবহিত করে স্কোপ হায়ারার্কির মাধ্যমে একটি ইভেন্টের নাম উপরের দিকে প্রেরণ করে

যেহেতু উপরের কোনও সুযোগ নেই $rootScope, তাই কোনও বুদবুদ হচ্ছে না। ইভেন্টবাস হিসাবে $rootScope.$emit()/ ব্যবহার করা সম্পূর্ণ নিরাপদ $rootScope.$on()

তবে এটি নিয়ন্ত্রণকারীদের মধ্যে থেকে ব্যবহার করার সময় একটি গ্যাচা রয়েছে। আপনি যদি $rootScope.$on()কোনও নিয়ামকের মধ্যে থেকে সরাসরি বাঁধাই করেন , আপনার স্থানীয়টি $scopeধ্বংস হয়ে যাওয়ার পরে আপনাকে নিজেকে নিজেকে বাইন্ডিং সাফ করতে হবে । এর কারণ হ'ল নিয়ন্ত্রকরা (পরিষেবাদির বিপরীতে) কোনও অ্যাপ্লিকেশন চলাকালীন একাধিকবার ইনস্ট্যান্টেশনযুক্ত হয়ে উঠতে পারেন যা ফলস্বরূপ পুরো জায়গা জুড়ে মেমরি ফাঁস তৈরির সংমিশ্রণ তৈরি করে :)

নিবন্ধন মুক্ত করার জন্য, শুধু আপনার শুনতে $scope'র $destroyএবং ইভেন্ট তারপর ফাংশন যা দ্বারা ফিরে ছিল কল $rootScope.$on

angular
    .module('MyApp')
    .controller('MyController', ['$scope', '$rootScope', function MyController($scope, $rootScope) {

            var unbind = $rootScope.$on('someComponent.someCrazyEvent', function(){
                console.log('foo');
            });

            $scope.$on('$destroy', unbind);
        }
    ]);

আমি বলব, এটি সত্যিই একটি কৌনিক নির্দিষ্ট জিনিস নয় কারণ এটি অন্যান্য ইভেন্টবাস বাস্তবায়নের ক্ষেত্রেও প্রযোজ্য, আপনাকে সংস্থানগুলি পরিষ্কার করতে হবে।

তবে আপনি সেই ক্ষেত্রে আপনার জীবনকে আরও সহজ করে তুলতে পারেন । উদাহরণস্বরূপ, আপনি বানর প্যাচ $rootScopeদিতে পারেন এবং এটি এমন একটি দিতে পারেন $onRootScopeযা এতে নির্গত ইভেন্টগুলিতে সাবস্ক্রাইব করে $rootScopeতবে স্থানীয় $scopeধ্বংস হয়ে গেলে সরাসরি হ্যান্ডলারটিকে পরিষ্কার করে দেয় ।

$rootScopeজাতীয় $onRootScopeপদ্ধতি সরবরাহের জন্য বানরকে প্যাচ করার সর্বোত্তম উপায়টি হবে কোনও ডেকরেটারের মাধ্যমে (কোনও রান ব্লক সম্ভবত এটি ঠিক ঠিক করবে তবে পিএসএসটি, কাউকে বলবেন না)

আমরা ব্যবহার করে সেট করে $onRootScopeরেখেছিলে গণনা করার সময় সম্পত্তিটি অপ্রত্যাশিত দেখাবে না তা নিশ্চিত করার জন্য । আপনার একটি ES5 শিম প্রয়োজন হতে পারে মনে রাখবেন।$scopeObject.defineProperty()enumerablefalse

angular
    .module('MyApp')
    .config(['$provide', function($provide){
        $provide.decorator('$rootScope', ['$delegate', function($delegate){

            Object.defineProperty($delegate.constructor.prototype, '$onRootScope', {
                value: function(name, listener){
                    var unsubscribe = $delegate.$on(name, listener);
                    this.$on('$destroy', unsubscribe);

                    return unsubscribe;
                },
                enumerable: false
            });


            return $delegate;
        }]);
    }]);

এই পদ্ধতিতে জায়গায় রেখে কন্ট্রোলার কোডটি উপরে থেকে সরল করা যেতে পারে:

angular
    .module('MyApp')
    .controller('MyController', ['$scope', function MyController($scope) {

            $scope.$onRootScope('someComponent.someCrazyEvent', function(){
                console.log('foo');
            });
        }
    ]);

সুতরাং এই সমস্তের চূড়ান্ত ফলাফল হিসাবে আমি আপনাকে $rootScope.$emit+ ব্যবহার করার পরামর্শ দিচ্ছি $scope.$onRootScope

বিটিডব্লু, আমি কৌণিক দলের মধ্যে সমস্যাটি সমাধান করার জন্য কৌনিক দলকে বোঝানোর চেষ্টা করছি। এখানে একটি আলোচনা চলছে: https://github.com/angular/angular.js/issues/4574

এখানে এমন একটি জাসস্পিফ রয়েছে যা দেখায় যে পারফেক্ট প্রভাবগুলি $broadcastকেবলমাত্র 100 এর সাথে একটি শালীন দৃশ্যে টেবিলে নিয়ে আসে $scope

http://jsperf.com/rootscope-emit-vs-rootscope-broadcast

jsperf ফলাফল


আমি আপনার ২ য় বিকল্পটি করার চেষ্টা করছি, তবে আমি একটি ত্রুটি পাচ্ছি: আনকাটড টাইপ এরির: সম্পত্তিটিকে নতুন করে সংজ্ঞা দেওয়া যায় না: Rআরটসকপ ঠিক যেখানে আমি অবজেক্ট.ডাইফাইনপ্রপার্টি করছি ....
স্কট

আমি এখানে পেস্ট করার সময় আমি কিছু ভুল করেছি। আমি এটি উত্পাদনে ব্যবহার করি এবং এটি দুর্দান্ত কাজ করে। আমি আগামীকাল একবার দেখে নেব :)
ক্রিস্টোফ

@ স্কট আমি এটি পেস্ট করেছি তবে কোডটি ইতিমধ্যে সঠিক ছিল এবং আমরা উত্পাদনে যা ব্যবহার করি ঠিক তেমনটাই। আপনি কি ডাবল চেক করতে পারেন, আপনার সাইটে আপনার টাইপো নেই? সমস্যা সমাধানের জন্য আমি কি আপনার কোডটি কোথাও দেখতে পাচ্ছি?
ক্রিস্টোফ

@ ক্রিসটফ আইই 8-তে সাজসজ্জার করার একটি ভাল উপায় আছে, কারণ এটি নন-ডোম অবজেক্টগুলিতে অবজেক্ট.ডেফাইনপ্রোটিকে সমর্থন করে না?
joshschreuder

59
এটি সমস্যার খুব চালাক সমাধান ছিল তবে এটির আর দরকার নেই needed অ্যাঙ্গুলার (1.2.16) এর সর্বশেষতম সংস্করণ এবং সম্ভবত এর আগেও এই সমস্যাটি স্থির হয়েছে। এখন $ সম্প্রচারটি কারণ অনুসারে প্রত্যেক বংশধর নিয়ামককে দেখতে পাবেন না। এটি কেবল যারা ইভেন্টটি শুনছেন তাদের সাথে দেখা করবেন। সমস্যাটি এখন ঠিক হয়ে গেছে তা দেখানোর জন্য আমি উপরের জেএসপিফের রেফারেন্স আপডেট করেছি: jsperf.com/rootscope-emit-vs-rootscope-broadcast/27
জুমালাইফগার্ড

107

শীর্ষ উত্তর এখানে একটি কৌণিক সমস্যা যা আর (অন্তত সংস্করণে> 1.2.16 এবং "সম্ভবত আগের") বিদ্যমান @zumalifeguard হিসেবে উল্লেখ করা থেকে কাছাকাছি একটি ছিল। তবে আমি আসল সমাধান ছাড়াই এই সমস্ত উত্তরগুলি পড়ে রেখেছি।

আমার কাছে মনে হচ্ছে উত্তরটি এখনই হওয়া উচিত

  • $broadcastথেকে ব্যবহার করুন$rootScope
  • $on স্থানীয়দের কাছ থেকে$scope এই ইভেন্টটি সম্পর্কে জানা দরকার তা ব্যবহার করে শুনুন

তাই প্রকাশ করতে

// EXAMPLE PUBLISHER
angular.module('test').controller('CtrlPublish', ['$rootScope', '$scope',
function ($rootScope, $scope) {

  $rootScope.$broadcast('topic', 'message');

}]);

এবং সাবস্ক্রাইব করুন

// EXAMPLE SUBSCRIBER
angular.module('test').controller('ctrlSubscribe', ['$scope',
function ($scope) {

  $scope.$on('topic', function (event, arg) { 
    $scope.receiver = 'got your ' + arg;
  });

}]);

Plunkers

আপনি স্থানীয় উপর শ্রোতা নিবন্ধিত হলে $scope, এটা হবে দ্বারা স্বয়ংক্রিয়ভাবে ধ্বংস $destroyনিজেই যখন যুক্ত নিয়ামক মুছে ফেলা হবে।


1
আপনি কি জানেন যদি controllerAsসিনট্যাক্সের সাথে একই প্যাটার্নটি ব্যবহার করা যায় ? $rootScopeইভেন্টটি শোনার জন্য আমি গ্রাহকটিতে ব্যবহার করতে সক্ষম হয়েছি , তবে অন্যরকম প্যাটার্ন থাকলে আমি কেবল কৌতূহলী ছিলাম।
এডেজেডে

3
@ সংযুক্তিগুলি আমি অনুমান করি আপনি $scopeসুস্পষ্টভাবে ইনজেক্ট করতে পারেন । জন পাপা$scope তার নিয়ন্ত্রকদের "আউট" রাখার নিয়মিত নিয়মের ঘটনাগুলিকে "ব্যতিক্রম" হওয়ার বিষয়ে লিখেছেন (আমি উক্তিগুলি ব্যবহার করি কারণ তিনি Controller Asএখনও উল্লেখ করেছেন $scope, এটি ঠিক বোনটের আওতায়)।
poshest

বোনটের নীচে আপনি কী বোঝাতে চেয়েছেন যে আপনি এখনও এটি ইঞ্জেকশনের মাধ্যমে পেতে পারেন?

2
@ সংযুক্তি আমি controller asঅনুরোধ হিসাবে একটি বাক্য গঠন বিকল্প দিয়ে আমার উত্তর আপডেট । আমি আশা করি আপনি এটাই বোঝাতে চেয়েছিলেন
poshest

3
@ এসডিএসএসএসডিএসডি, পরিষেবা / কারখানা / সরবরাহকারীরা চিরকাল থাকবে। একটি কৌণিক অ্যাপে সর্বদা তাদের মধ্যে একটি এবং সিলেটলেট রয়েছে। অন্যদিকে কন্ট্রোলারগুলি কার্যকারিতার সাথে আবদ্ধ থাকে: উপাদান / নির্দেশনা / এনজি-কন্ট্রোলার, যা পুনরাবৃত্তি হতে পারে (শ্রেণীর তৈরি জিনিসগুলির মতো) এবং তারা প্রয়োজনীয়ভাবে আসে এবং যায়। যখন আপনার আর প্রয়োজন নেই তখন আপনি কেন নিয়ন্ত্রণ এবং এর নিয়ামককে বিদ্যমান রাখতে চান? এটি একটি স্মৃতি ফাঁসের খুব সংজ্ঞা।
15:37

54

ব্যবহার $ rootScope। $ সম্প্রচারের এবং $ সুযোগ। $ একটি PubSub যোগাযোগের জন্য করে।

এছাড়াও, এই পোস্টটি দেখুন: AngularJS - নিয়ন্ত্রণকারীদের মধ্যে যোগাযোগ করা


3
এই ভিডিওটি কেবল পুনরায় উদ্ভাবন করে $rootScopeএবং $watch। নিশ্চিত যে এটি কোন উন্নতি।
নীলস্কেপি

42

যেহেতু DefineProperty এর ব্রাউজারের সামঞ্জস্যের সমস্যা রয়েছে তাই আমি মনে করি আমরা কোনও পরিষেবা ব্যবহারের বিষয়ে ভাবতে পারি।

angular.module('myservice', [], function($provide) {
    $provide.factory('msgBus', ['$rootScope', function($rootScope) {
        var msgBus = {};
        msgBus.emitMsg = function(msg) {
        $rootScope.$emit(msg);
        };
        msgBus.onMsg = function(msg, scope, func) {
            var unbind = $rootScope.$on(msg, func);
            scope.$on('$destroy', unbind);
        };
        return msgBus;
    }]);
});

এবং এটি নিয়ামক হিসাবে এটি ব্যবহার করুন:

  • নিয়ামক 1

    function($scope, msgBus) {
        $scope.sendmsg = function() {
            msgBus.emitMsg('somemsg')
        }
    }
  • নিয়ামক 2

    function($scope, msgBus) {
        msgBus.onMsg('somemsg', $scope, function() {
            // your logic
        });
    }

7
সুযোগটি নষ্ট হয়ে গেলে স্বয়ংক্রিয় আনসস্ক্রিপশনের জন্য +1।
ফেডেরিকো নাফরিয়া

6
আমি এই সমাধানটি পছন্দ করি। 2 টি পরিবর্তন আমি করেছি: (1) ব্যবহারকারীকে এমিট বার্তায় 'ডেটা' পাস করার মঞ্জুরি দেয় (২) 'স্কোপ' passingচ্ছিকভাবে উত্তরণ করা যাতে এটি সিঙ্গেলটন পরিষেবাগুলির পাশাপাশি নিয়ন্ত্রণকারীগুলিতেও ব্যবহার করা যায়। আপনি এই পরিবর্তনগুলি এখানে বাস্তবায়িত দেখতে পারেন: gist.github.com/turtlemonvh/10686980/…
টার্টলমনভ


15

প্রকৃতপক্ষে ইমিট এবং সম্প্রচার ব্যবহার অকার্যকর কারণ ইভেন্টটি স্কোপ শ্রেণিবিন্যাসকে উপরে এবং নীচে বুদ্বুদ দেয় যা কোনও জটিল অ্যাপ্লিকেশনের জন্য পারফরম্যান্স বোলেমেন্টে সহজেই হ্রাস করতে পারে।

আমি কোনও পরিষেবা ব্যবহার করার পরামর্শ দেব। আমি সম্প্রতি আমার প্রকল্পগুলির একটিতে এটি কীভাবে বাস্তবায়ন করেছি তা এখানে - https://gist.github.com/3384419

বেসিক ধারণা - পরিষেবা হিসাবে একটি পাবসব / ইভেন্ট বাসটি নিবন্ধ করুন। তারপরে সেই ইভেন্টবাসটি ইনজেক্ট করুন যেখানে কখনও আপনার ইভেন্ট / বিষয়গুলি সাবস্ক্রাইব বা প্রকাশ করতে হবে।


7
এবং যখন কোনও নিয়ামকের প্রয়োজন হয় না, আপনি কীভাবে এটি স্বয়ংক্রিয়ভাবে সদস্যতা ত্যাগ করবেন? আপনি যদি এটি না করেন, বন্ধ হওয়ার কারণে নিয়ামকটি কখনই মেমরি থেকে সরানো হবে না এবং আপনি এখনও এতে বার্তা সেন্সিং করতে পারবেন। এটি এড়াতে আপনাকে ম্যানুয়ালি এর পরে অপসারণ করতে হবে। এতে $ ব্যবহার করা হবে না।
রেনান তোমল ফার্নান্দেস

1
একটি সুস্পষ্ট পয়েন্ট। আমি মনে করি আপনি কীভাবে আপনার অ্যাপ্লিকেশনটি আর্কিটেক্ট করেন এটির মাধ্যমে সমাধান করা যেতে পারে। আমার ক্ষেত্রে, আমার একটি একক পৃষ্ঠার অ্যাপ্লিকেশন রয়েছে যাতে এটি আরও ম্যানেজযোগ্য সমস্যা। বলার পরেও, আমি মনে করি যদি কৌণিকের এমন উপাদান উপাদান লাইকসাইকেল হুক থাকে যেখানে আপনি এই জাতীয় জিনিসগুলি তারের / আনওয়্যার করতে পারেন তবে এটি অনেক বেশি পরিষ্কার হবে।
নুমান সালাতী

6
আমি এটিকে এখানেই রেখেছি যেমন আগে কেউ এটি বলেছিল না। ইভেন্টবাস হিসাবে রুটস্কোপ ব্যবহার কেবলমাত্র উপরের দিকে বুদবুদ হিসাবে অক্ষম নয়$rootScope.$emit() । যাইহোক, উপরোক্ত কোনও সুযোগ $rootScopeনেই বলে ভয় পাওয়ার কিছু নেই। সুতরাং আপনি যদি কেবলমাত্র ব্যবহার করছেন $rootScope.$emit()এবং $rootScope.$on()আপনার কাছে একটি দ্রুত সিস্টেম প্রশস্ত ইভেন্টবাস থাকবে।
ক্রিস্টোফ

1
কেবলমাত্র আপনার সচেতন হওয়া দরকার তা হ'ল আপনি যদি $rootScope.$on()আপনার নিয়ামকের ভিতরে ব্যবহার করেন তবে আপনাকে ইভেন্টের বাইন্ডিং পরিষ্কার করতে হবে অন্যথায় তারা সংশ্লেষ করবে কারণ প্রতিবার নিয়ামক তাত্ক্ষণিকভাবে ইনস্টল করার সময় তারা একটি নতুন তৈরি করে এবং তারা তা করে না আপনি $rootScopeসরাসরি বাঁধাই হওয়ায় আপনার জন্য স্বয়ংক্রিয়ভাবে ধ্বংস হয়ে যান ।
ক্রিস্টোফ

অ্যাঙ্গুলার (1.2.16) এর সর্বশেষতম সংস্করণ এবং সম্ভবত এর আগেও এই সমস্যাটি স্থির হয়েছে। এখন $ সম্প্রচারটি কারণ অনুসারে প্রত্যেক বংশধর নিয়ামককে দেখতে পাবেন না। এটি কেবল যারা ইভেন্টটি শুনছেন তাদের সাথে দেখা করবেন। সমস্যাটি এখন ঠিক হয়ে গেছে তা দেখানোর জন্য আমি উপরের জেএসপিফের রেফারেন্স আপডেট করেছি: jsperf.com/rootscope-emit-vs-rootscope-broadcast/27
জুমালাইফগার্ড

14

কোনও পরিষেবার মধ্যে গেট অ্যান্ড সেট পদ্ধতি ব্যবহার করে আপনি খুব সহজেই নিয়ন্ত্রণকারীদের মধ্যে বার্তা প্রেরণ করতে পারেন।

var myApp = angular.module("myApp",[]);

myApp.factory('myFactoryService',function(){


    var data="";

    return{
        setData:function(str){
            data = str;
        },

        getData:function(){
            return data;
        }
    }


})


myApp.controller('FirstController',function($scope,myFactoryService){
    myFactoryService.setData("Im am set in first controller");
});



myApp.controller('SecondController',function($scope,myFactoryService){
    $scope.rslt = myFactoryService.getData();
});

এইচটিএমএল এইচটিএমএলে আপনি এটি চেক করতে পারেন

<div ng-controller='FirstController'>  
</div>

<div ng-controller='SecondController'>
    {{rslt}}
</div>

+1 সেই-স্পষ্ট-একবার-আপনাকে-বলা-হওয়ার পদ্ধতিগুলির মধ্যে একটি - দুর্দান্ত! আমি সেট (কী, মান) এবং আরও একটি সাধারণ সংস্করণ প্রয়োগ করেছি (কী) পদ্ধতিগুলি - $ সম্প্রচারের একটি দরকারী বিকল্প।
টনিউইলক

8

মূল কোড সম্পর্কিত - এটি প্রদর্শিত হয় আপনি স্কোপগুলির মধ্যে ডেটা ভাগ করতে চান। ডেটা বা স্টেটের মধ্যে share স্কোপের মধ্যে ভাগ করে নিতে ডক্স একটি পরিষেবা ব্যবহারের পরামর্শ দেয়:

  • নিয়ন্ত্রণকারীদের জুড়ে স্টেটলেস বা রাষ্ট্রীয় কোড চালনার জন্য - পরিবর্তে কৌণিক পরিষেবা ব্যবহার করুন।
  • অন্যান্য উপাদানগুলির জীবনচক্রটি ইনস্ট্যান্ট করতে বা পরিচালনা করতে (উদাহরণস্বরূপ, পরিষেবা দৃষ্টান্ত তৈরি করতে)।

রেফ: কৌনিক ডক্স লিঙ্কটি এখানে


5

আমি কন্ট্রোলারদের মধ্যে একটি বার্তা বাস হিসাবে পোস্টেল জেজে আসলে ব্যবহার শুরু করেছি।

এএমকিপি স্টাইলের বাইন্ডিংস, ডাক ডাব্লু / আইফ্রেমস এবং ওয়েব সকেটগুলিকে আরও একীভূত করতে পারে এমন বার্তা বাস হিসাবে এর প্রচুর উপকার রয়েছে it

পোস্ট সেট আপ করার জন্য আমি একটি ডেকরেটার ব্যবহার করেছি $scope.$bus...

angular.module('MyApp')  
.config(function ($provide) {
    $provide.decorator('$rootScope', ['$delegate', function ($delegate) {
        Object.defineProperty($delegate.constructor.prototype, '$bus', {
            get: function() {
                var self = this;

                return {
                    subscribe: function() {
                        var sub = postal.subscribe.apply(postal, arguments);

                        self.$on('$destroy',
                        function() {
                            sub.unsubscribe();
                        });
                    },
                    channel: postal.channel,
                    publish: postal.publish
                };
            },
            enumerable: false
        });

        return $delegate;
    }]);
});

এখানে বিষয়বস্তুতে একটি ব্লগ পোস্টের একটি লিঙ্ক ...
http://jonathancreamer.com/an-angular-event-bus-with-postal-js/


3

আমি ফ্যাক্টরি / পরিষেবাদি এবং সাধারণ নির্ভরতা ইনজেকশন (ডিআই) দিয়ে এটিই করি ।

myApp = angular.module('myApp', [])

# PeopleService holds the "data".
angular.module('myApp').factory 'PeopleService', ()->
  [
    {name: "Jack"}
  ]

# Controller where PeopleService is injected
angular.module('myApp').controller 'PersonFormCtrl', ['$scope','PeopleService', ($scope, PeopleService)->
  $scope.people = PeopleService
  $scope.person = {} 

  $scope.add = (person)->
    # Simply push some data to service
    PeopleService.push angular.copy(person)
]

# ... and again consume it in another controller somewhere...
angular.module('myApp').controller 'PeopleListCtrl', ['$scope','PeopleService', ($scope, PeopleService)->
  $scope.people = PeopleService
]

1
আপনার দুটি নিয়ামক যোগাযোগ করেন না, তারা কেবলমাত্র একই পরিষেবা ব্যবহার করেন। এটি একই জিনিস নয়।
গ্রেগ

@ গ্রেগ আপনি একটি ভাগ করা পরিষেবা পেয়ে এবং প্রয়োজন যেখানে ঘড়ি যুক্ত করে কম কোড দিয়ে একই জিনিস অর্জন করতে পারেন।
কপাজ

3

$rootscope.emitআন্তঃসংযোগ অর্জনের জন্য কীভাবে ব্যবহৃত হয়েছিল তা আমার পছন্দ হয়েছিল। আমি গ্লোবাল স্পেসকে দূষিত না করে পরিষ্কার এবং কর্মক্ষমতা কার্যকর সমাধানের পরামর্শ দিচ্ছি।

module.factory("eventBus",function (){
    var obj = {};
    obj.handlers = {};
    obj.registerEvent = function (eventName,handler){
        if(typeof this.handlers[eventName] == 'undefined'){
        this.handlers[eventName] = [];  
    }       
    this.handlers[eventName].push(handler);
    }
    obj.fireEvent = function (eventName,objData){
       if(this.handlers[eventName]){
           for(var i=0;i<this.handlers[eventName].length;i++){
                this.handlers[eventName][i](objData);
           }

       }
    }
    return obj;
})

//Usage:

//In controller 1 write:
eventBus.registerEvent('fakeEvent',handler)
function handler(data){
      alert(data);
}

//In controller 2 write:
eventBus.fireEvent('fakeEvent','fakeData');

মেমরি ফাঁসের জন্য আপনার ইভেন্ট শ্রোতাদের কাছ থেকে নিবন্ধন করার জন্য একটি অতিরিক্ত পদ্ধতি যুক্ত করা উচিত। যাইহোক ভাল তুচ্ছ নমুনা
রাফায়েউ

2

এখানে দ্রুত এবং নোংরা উপায়।

// Add $injector as a parameter for your controller

function myAngularController($scope,$injector){

    $scope.sendorders = function(){

       // now you can use $injector to get the 
       // handle of $rootScope and broadcast to all

       $injector.get('$rootScope').$broadcast('sinkallships');

    };

}

যে কোনও ভাইবাল নিয়ন্ত্রণকারীদের মধ্যে যোগ করার জন্য এখানে একটি উদাহরণ ফাংশন রয়েছে:

$scope.$on('sinkallships', function() {

    alert('Sink that ship!');                       

});

এবং অবশ্যই এখানে আপনার এইচটিএমএল:

<button ngclick="sendorders()">Sink Enemy Ships</button>

16
আপনি শুধু ইনজেকশন না কেন $rootScope?
পিটার হেরোইলেন

1

কৌণিক 1.5 শুরু হচ্ছে এবং এটি উপাদান ভিত্তিক বিকাশ ফোকাস। উপাদানগুলির ইন্টারঅ্যাক্ট করার জন্য প্রস্তাবিত উপায় হ'ল 'প্রয়োজনীয়' সম্পত্তি ব্যবহারের মাধ্যমে এবং সম্পত্তি বাঁধার (ইনপুট / আউটপুট) মাধ্যমে।

কোনও উপাদানটির জন্য অন্য উপাদান প্রয়োজন (উদাহরণস্বরূপ মূল উপাদান) এবং এটির নিয়ামকের একটি রেফারেন্স পাবেন:

angular.module('app').component('book', {
    bindings: {},
    require: {api: '^app'},
    template: 'Product page of the book: ES6 - The Essentials',
    controller: controller
});

তারপরে আপনি আপনার সন্তানের উপাদানটিতে মূল উপাদানটির পদ্ধতিগুলি ব্যবহার করতে পারেন:

$ctrl.api.addWatchedBook('ES6 - The Essentials');

এটি মূল উপাদান নিয়ন্ত্রক ফাংশন:

function addWatchedBook(bookName){

  booksWatched.push(bookName);

}

এখানে একটি সম্পূর্ণ স্থাপত্য ওভারভিউ রয়েছে: কম্পোনেন্ট কমিউনিকেশনস


0

আপনি মডিউলের যে কোনও জায়গায় এই হ্যালো ফাংশনটিতে অ্যাক্সেস করতে পারেন

নিয়ামক এক

 $scope.save = function() {
    $scope.hello();
  }

দ্বিতীয় নিয়ামক

  $rootScope.hello = function() {
    console.log('hello');
  }

আরও তথ্য এখানে


7
পার্টিতে কিছুটা দেরি হলেও: এটি করবেন না। রুট স্কোপটিতে একটি ফাংশন রাখা কোনও ফাংশনকে বিশ্বব্যাপী তৈরি করার অনুরূপ, যা সকল ধরণের সমস্যা সৃষ্টি করতে পারে।
ড্যান প্যান্ট্রি

0

আমি একটি পরিষেবা তৈরি করব এবং বিজ্ঞপ্তি ব্যবহার করব।

  1. বিজ্ঞপ্তি পরিষেবাটিতে একটি পদ্ধতি তৈরি করুন
  2. বিজ্ঞপ্তি পরিষেবাতে বিজ্ঞপ্তি সম্প্রচারের জন্য একটি জেনেরিক পদ্ধতি তৈরি করুন।
  3. সোর্স কন্ট্রোলার থেকে নোটিফিকেশনসোর্সেস.মথোদকে কল করুন। প্রয়োজন বজায় রাখার জন্য আমি সংশ্লিষ্ট জিনিসটিও পাস করি pass
  4. পদ্ধতির মধ্যে, আমি বিজ্ঞপ্তি পরিষেবাতে ডেটা বজায় রাখি এবং জেনেরিক নোটিফিক পদ্ধতিতে কল করি।
  5. গন্তব্য নিয়ন্ত্রকটিতে আমি সম্প্রচার ইভেন্ট এবং বিজ্ঞপ্তি পরিষেবা থেকে ডেটা অ্যাক্সেসের জন্য শুনি ($ স্কোপ.অন)।

যে কোনও সময়ে নোটিফিকেশন পরিষেবাটি সিঙ্গলটন হিসাবে এটি জুড়ে স্থায়ী ডেটা সরবরাহ করতে সক্ষম হওয়া উচিত।

আশাকরি এটা সাহায্য করবে


0

আপনি অ্যাংুলারজেএস বিল্ট-ইন পরিষেবাটি ব্যবহার করতে পারেন $rootScopeএবং আপনার উভয় নিয়ামককেই এই পরিষেবাটি ইনজেক্ট করতে পারেন । এরপরে আপনি events rootScope অবজেক্টে গুলি চালানো ইভেন্টগুলি শুনতে পারেন।

$ রুটস্কোপ দুটি ইভেন্ট প্রেরণকারী সরবরাহ করে $emit and $broadcastযা ইভেন্ট প্রেরণের জন্য দায়ী (কাস্টম ইভেন্ট হতে পারে) এবং $rootScope.$onইভেন্ট শ্রোতাদের যুক্ত করতে ফাংশন ব্যবহার করে।


0

আপনার পরিষেবাটি ব্যবহার করা উচিত, কারণ $rootscopeপুরো অ্যাপ্লিকেশন থেকে অ্যাক্সেস পাওয়া যায় এবং এটি লোড বাড়িয়ে তোলে, বা আপনি যদি ডেটা বেশি না করেন তবে আপনি রুটপ্রেমগুলি ব্যবহার করেন।


0
function mySrvc() {
  var callback = function() {

  }
  return {
    onSaveClick: function(fn) {
      callback = fn;
    },
    fireSaveClick: function(data) {
      callback(data);
    }
  }
}

function controllerA($scope, mySrvc) {
  mySrvc.onSaveClick(function(data) {
    console.log(data)
  })
}

function controllerB($scope, mySrvc) {
  mySrvc.fireSaveClick(data);
}

0

আপনি কৌনিক ইভেন্টগুলি mit নির্গত এবং $ সম্প্রচারটি ব্যবহার করে এটি করতে পারেন। আমাদের জ্ঞান অনুযায়ী এটি সর্বোত্তম, দক্ষ ও কার্যকর উপায়।

প্রথমে আমরা একটি নিয়ামক থেকে একটি ফাংশন কল।

var myApp = angular.module('sample', []);
myApp.controller('firstCtrl', function($scope) {
    $scope.sum = function() {
        $scope.$emit('sumTwoNumber', [1, 2]);
    };
});
myApp.controller('secondCtrl', function($scope) {
    $scope.$on('sumTwoNumber', function(e, data) {
        var sum = 0;
        for (var a = 0; a < data.length; a++) {
            sum = sum + data[a];
        }
        console.log('event working', sum);

    });
});

আপনি $ সুযোগের জায়গায় $ রুটস্কোপ ব্যবহার করতে পারেন। সেই অনুযায়ী আপনার নিয়ামক ব্যবহার করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.