javascript - क्या एक नियंत्रक दूसरे को कॉल कर सकता है?




html angularjs (9)

क्या एक नियंत्रक दूसरे का उपयोग करना संभव है?

उदाहरण के लिए:

यह HTML दस्तावेज़ संदेश messageCtrl.js फ़ाइल में MessageCtrl नियंत्रक द्वारा वितरित एक संदेश को प्रिंट करता है।

<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 जिसने तारीख को एक विशिष्ट प्रारूप में DateCtrl वापस सौंप दिया था, तो कोई ऐसा करने के लिए कैसे जाएगा? डी ढांचे को XmlHttpRequests और सेवाओं तक पहुंचने के लिए चिंतित लगता है।


असल में उत्सर्जन और प्रसारण का उपयोग अक्षम है क्योंकि घटना स्कोप पदानुक्रम को ऊपर और नीचे बुलबुला करती है जो जटिल अनुप्रयोग के लिए प्रदर्शन बोतल में आसानी से गिरावट कर सकती है।

मैं एक सेवा का उपयोग करने का सुझाव दूंगा। यहां बताया गया है कि मैंने हाल ही में अपनी परियोजनाओं में से एक में इसे कैसे कार्यान्वित किया - https://gist.github.com/3384419

मूल विचार - एक सेवा के रूप में एक पब-सब / घटना बस पंजीकृत करें। फिर उस ईवेंट बस को इंजेक्ट करें जहां आपको कभी भी ईवेंट / विषयों की सदस्यता लेने या प्रकाशित करने की आवश्यकता होती है।


आप अपने माता-पिता नियंत्रक (MessageCtrl) में '$ नियंत्रक' सेवा इंजेक्ट कर सकते हैं और उसके बाद बाल नियंत्रक (DateCtrl) को तत्काल / इंजेक्ट कर सकते हैं:
$scope.childController = $controller('childController', { $scope: $scope.$new() });

अब आप अपनी विधियों को कॉल करके अपने बच्चे नियंत्रक से डेटा तक पहुंच सकते हैं क्योंकि यह एक सेवा है।
अगर कोई मुद्दा है तो मुझे बताएं।


कोणीय 1.5 में यह निम्नलिखित करके पूरा किया जा सकता है:

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

}());

यह मूल घटक है। इस में मैंने एक ऐसा फ़ंक्शन बनाया है जो मेरे productForms में किसी अन्य ऑब्जेक्ट को धक्का देता है productForms सरणी - नोट - यह सिर्फ मेरा उदाहरण है, यह फ़ंक्शन वास्तव में कुछ भी हो सकता है।

अब हम एक और घटक बना सकते हैं जो 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;
    };  
  }

}());

यहां बाल घटक माता-पिता घटक फ़ंक्शन addNewForm संदर्भ addNewForm जो तब HTML से बाध्य हो सकता है और किसी अन्य फ़ंक्शन की तरह कहा जा सकता है।


दो और झुकाव: (गैर सेवा दृष्टिकोण)

1) अभिभावक के लिए- बाल नियंत्रक - घटनाओं को उत्सर्जित / प्रसारित करने के लिए अभिभावक नियंत्रक के $scope का उपयोग करना। http://jsfiddle.net/laan_sachin/jnj6y/

2) गैर-संबंधित नियंत्रकों में $rootScope का उपयोग करना। jsfiddle.net/VxafF


नियंत्रकों के बीच संवाद करने के कई तरीके हैं।

सबसे अच्छा शायद एक सेवा साझा कर रहा है:

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

दोनों मामलों में, आप किसी भी निर्देश के साथ संवाद कर सकते हैं।


मुझे नहीं पता कि यह मानकों से बाहर है, लेकिन यदि आपके पास एक ही फाइल पर आपके सभी नियंत्रक हैं, तो आप ऐसा कुछ कर सकते हैं:

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

जैसा कि आप updateCharts को कॉल करते समय संकेतक देख सकते हैं Ctrl अन्य दोनों नियंत्रकों के अद्यतन चार्ट फ़ंक्शन को कॉल कर रहा है।


यदि आप एक नियंत्रक को दूसरे में कॉल करना चाहते हैं तो चार विधियां उपलब्ध हैं

  1. $ rootScope। $ emit () और $ rootScope। $ प्रसारण ()
  2. यदि दूसरा नियंत्रक बच्चा है, तो आप अभिभावक बाल संचार का उपयोग कर सकते हैं।
  3. सेवाओं का प्रयोग करें
  4. हैक की तरह - angular.element () की मदद से

1. $ rootScope। $ Emit () और $ rootScope। $ प्रसारण ()

नियंत्रक और इसका दायरा नष्ट हो सकता है, लेकिन $ रूटस्कोप एप्लिकेशन भर में बना रहता है, यही कारण है कि हम $ रूटस्कोप ले रहे हैं क्योंकि $ रूटस्कोप सभी क्षेत्रों के माता-पिता हैं।

यदि आप माता-पिता से बच्चे से संचार कर रहे हैं और यहां तक ​​कि बच्चा अपने भाई बहनों के साथ संवाद करना चाहता है, तो आप $ प्रसारण का उपयोग कर सकते हैं

यदि आप बच्चे से माता-पिता से संचार कर रहे हैं, तो कोई भाई बहन नहीं आती है तो आप $ रूटस्कोप का उपयोग कर सकते हैं। $ Emit

एचटीएमएल

<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' के उपरोक्त कोड कंसोल में बच्चे के भाई बहनों के अंदर फोन नहीं किया जाएगा और यह केवल माता-पिता के अंदर कॉल करेगा, जहां भाई बहनों और माता-पिता के अंदर $ प्रसारण भी कहा जाता है। यह वह जगह है जहां प्रदर्शन एक क्रिया में आता है। $ Emit है प्राथमिकता, अगर आप बच्चे को माता-पिता के संचार के लिए उपयोग कर रहे हैं क्योंकि यह कुछ गंदे चेक छोड़ देता है।

2. यदि दूसरा नियंत्रक बच्चा है, तो आप बाल अभिभावक संचार का उपयोग कर सकते हैं

यह सबसे अच्छी विधि है, यदि आप बाल अभिभावक संचार करना चाहते हैं जहां बच्चा तत्काल माता - पिता के साथ संवाद करना चाहता है तो उसे किसी भी प्रकार के $ प्रसारण या $ उत्सर्जन की आवश्यकता नहीं होगी, लेकिन यदि आप माता-पिता से बच्चे से संचार करना चाहते हैं तो आपको या तो सेवा या $ प्रसारण का उपयोग करें

उदाहरण के लिए एचटीएमएल: -

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

जब भी आप बच्चे को माता-पिता के संचार के लिए उपयोग कर रहे हों, तो Angularjs बच्चे के अंदर एक चर के लिए खोज करेगा, अगर यह अंदर मौजूद नहीं है तो यह मूल नियंत्रक के अंदर मानों को देखना चुन देगा।

3. सेवाओं का उपयोग करें

AngularJS सेवाओं की वास्तुकला का उपयोग कर "चिंता का विषय " की अवधारणाओं का समर्थन करता है। सेवाएं जावास्क्रिप्ट फ़ंक्शंस हैं और केवल एक विशिष्ट कार्य करने के लिए ज़िम्मेदार हैं। इससे उन्हें एक व्यक्तिगत इकाई मिलती है जो रखरखाव योग्य और टेस्टेबल होती है। सर्विसेज एंगुलरजेस के निर्भरता इंजेक्शन मेकैनिज्म का उपयोग करके इंजेक्ट करने के लिए उपयोग की जाती है।

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

यह आउटपुट हैलो चाइल्ड वर्ल्ड और हैलो पैरेंट वर्ल्ड देगा। सेवा सिंगलटन के कोणीय दस्तावेज़ों के अनुसार - सेवा पर निर्भर प्रत्येक घटक सेवा कारखाने द्वारा उत्पन्न एकल उदाहरण का संदर्भ प्राप्त करता है

4. हैक की खोज - angular.element () की मदद से

इस विधि को उसके आईडी / अद्वितीय class.angular.element () विधि रिटर्न तत्व और स्कोप () द्वारा तत्व से स्कोप () प्राप्त होता है, एक दूसरे के अंदर एक नियंत्रक के $ स्कोप वैरिएबल का उपयोग करके किसी अन्य चर के $ स्कोप वैरिएबल को एक अच्छा अभ्यास नहीं है।

एचटीएमएल: -

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

उपरोक्त कोड नियंत्रक एचटीएमएल पर अपना खुद का मूल्य दिखा रहे हैं और जब आप टेक्स्ट पर क्लिक करेंगे तो आपको तदनुसार कंसोल में वैल्यू मिलेंगे। अगर आप अभिभावक नियंत्रक अवधि पर क्लिक करते हैं, तो ब्राउज़र बच्चे और वाइसवर्सा का मूल्य कंसोल करेगा।


यह पहेली देखें: http://jsfiddle.net/simpulton/XqDxG/

निम्नलिखित वीडियो भी देखें: नियंत्रकों के बीच संचार

एचटीएमएल:

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

यदि आप नियंत्रकों में डेटा साझा करने या कॉल करने के लिए ईवेंट को उत्सर्जित और प्रसारित करना चाहते हैं , तो कृपया इस link : और zbynour (अधिकतम वोटों के साथ उत्तर) द्वारा उत्तर की जांच करें। मैं उसका जवाब उद्धृत कर रहा हूं !!!

यदि firstCtrl का दायरा दूसरे Ctrl स्कोप का अभिभावक है, तो आपके कोड को $ emit को $ प्रसारण द्वारा पहले स्थानांतरित करके काम करना चाहिए:

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

अंत में, जब आपको बच्चे के नियंत्रक से घटना को प्रेषित करने की आवश्यकता होती है तो आप $ स्कोप का उपयोग कर सकते हैं। $ Emit। यदि firstCtrl का दायरा दूसरे Ctrl स्कोप का अभिभावक है:

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

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






angularjs