[Angularjs] एंगुलरजेएस निर्देश में परिभाषित विधि को कैसे कॉल करें?



Answers

यह मानते हुए कि एक्शन बटन निर्देश के रूप में एक ही नियंत्रक $scope का उपयोग करता है, बस लिंक फ़ंक्शन के अंदर $scope पर फ़ंक्शन updateMap को परिभाषित करता है। जब कार्रवाई बटन क्लिक किया जाता है तो आपका नियंत्रक तब उस फ़ंक्शन को कॉल कर सकता है।

<div ng-controller="MyCtrl">
    <map></map>
    <button ng-click="updateMap()">call updateMap()</button>
</div>
app.directive('map', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<div></div>',
        link: function($scope, element, attrs) {
            $scope.updateMap = function() {
                alert('inside updateMap()');
            }
        }
    }
});

fiddle

@ फ्लोरियनएफ की टिप्पणी के अनुसार, यदि निर्देश एक अलग दायरे का उपयोग करता है, तो चीजें अधिक जटिल होती हैं। इसे काम करने का एक तरीका यहां दिया गया है: map निर्देश में एक set-fn विशेषता जोड़ें जो नियंत्रक के साथ निर्देश फ़ंक्शन पंजीकृत करेगा:

<map set-fn="setDirectiveFn(theDirFn)"></map>
<button ng-click="directiveFn()">call directive function</button>
scope: { setFn: '&' },
link: function(scope, element, attrs) {
    scope.updateMap = function() {
       alert('inside updateMap()');
    }
    scope.setFn({theDirFn: scope.updateMap});
}
function MyCtrl($scope) {
    $scope.setDirectiveFn = function(directiveFn) {
        $scope.directiveFn = directiveFn;
    };
}

fiddle

Question

मेरे पास निर्देश है, यहां कोड है:

.directive('map', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<div></div>',
        link: function($scope, element, attrs) {

            var center = new google.maps.LatLng(50.1, 14.4); 
            $scope.map_options = {
                zoom: 14,
                center: center,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            // create map
            var map = new google.maps.Map(document.getElementById(attrs.id), $scope.map_options);
            var dirService= new google.maps.DirectionsService();
            var dirRenderer= new google.maps.DirectionsRenderer()

            var showDirections = function(dirResult, dirStatus) {
                if (dirStatus != google.maps.DirectionsStatus.OK) {
                    alert('Directions failed: ' + dirStatus);
                    return;
                  }
                  // Show directions
                dirRenderer.setMap(map);
                //$scope.dirRenderer.setPanel(Demo.dirContainer);
                dirRenderer.setDirections(dirResult);
            };

            // Watch
            var updateMap = function(){
                dirService.route($scope.dirRequest, showDirections); 
            };    
            $scope.$watch('dirRequest.origin', updateMap);

            google.maps.event.addListener(map, 'zoom_changed', function() {
                $scope.map_options.zoom = map.getZoom();
              });

            dirService.route($scope.dirRequest, showDirections);  
        }
    }
})

मैं उपयोगकर्ता कार्रवाई पर updateMap() को कॉल करना चाहता हूं। कार्रवाई बटन निर्देश पर नहीं है।

नियंत्रक से updateMap() को कॉल करने का सबसे अच्छा तरीका क्या है?




ईमानदार होने के लिए, मैं वास्तव में इस धागे में किसी भी उत्तर के साथ आश्वस्त नहीं था। तो, यहां मेरे समाधान हैं:

निर्देश हैंडलर (प्रबंधक) दृष्टिकोण

यह विधि अज्ञात है कि निर्देश का $scope एक साझा या अलग है या नहीं

निर्देशक उदाहरण पंजीकृत करने के लिए एक factory

angular.module('myModule').factory('MyDirectiveHandler', function() {
    var instance_map = {};
    var service = {
        registerDirective: registerDirective,
        getDirective: getDirective,
        deregisterDirective: deregisterDirective
    };

    return service;

    function registerDirective(name, ctrl) {
        instance_map[name] = ctrl;
    }

    function getDirective(name) {
        return instance_map[name];
    }

    function deregisterDirective(name) {
        instance_map[name] = null;
    }
});

निर्देश कोड, मैं आमतौर पर सभी तर्क डालता हूं जो निर्देशक नियंत्रक के अंदर डीओएम से निपटता नहीं है। और हमारे हैंडलर के अंदर नियंत्रक उदाहरण दर्ज करना

angular.module('myModule').directive('myDirective', function(MyDirectiveHandler) {
    var directive = {
        link: link,
        controller: controller
    };

    return directive;

    function link() {
        //link fn code
    }

    function controller($scope, $attrs) {
        var name = $attrs.name;

        this.updateMap = function() {
            //some code
        };

        MyDirectiveHandler.registerDirective(name, this);

        $scope.$on('destroy', function() {
            MyDirectiveHandler.deregisterDirective(name);
        });
    }
})

टेम्पलेट कोड

<div my-directive name="foo"></div>

factory का उपयोग कर नियंत्रक उदाहरण तक पहुंचें और सार्वजनिक रूप से उजागर विधियों को चलाएं

angular.module('myModule').controller('MyController', function(MyDirectiveHandler, $scope) {
    $scope.someFn = function() {
        MyDirectiveHandler.get('foo').updateMap();
    };
});

कोणीय दृष्टिकोण

कोणीय की किताब से बाहर एक पत्ता लेना कि वे किस तरह से निपटते हैं

<form name="my_form"></form>

$parse का उपयोग करके और $parent दायरे पर नियंत्रक को पंजीकृत करना। यह तकनीक अलग-अलग $scope निर्देशों पर काम नहीं करती है।

angular.module('myModule').directive('myDirective', function($parse) {
    var directive = {
        link: link,
        controller: controller,
        scope: true
    };

    return directive;

    function link() {
        //link fn code
    }

    function controller($scope, $attrs) {
        $parse($attrs.name).assign($scope.$parent, this);

        this.updateMap = function() {
            //some code
        };
    }
})

$scope.foo का उपयोग कर नियंत्रक के अंदर इसे एक्सेस करें

angular.module('myModule').controller('MyController', function($scope) {
    $scope.someFn = function() {
        $scope.foo.updateMap();
    };
});



परीक्षण आशा है कि यह किसी की मदद करता है।

मेरा सरल दृष्टिकोण (टैग को अपने मूल कोड के रूप में सोचें)

<html>
<div ng-click="myfuncion"> 
<my-dir callfunction="myfunction">
</html>

<directive "my-dir">
callfunction:"=callfunction"
link : function(scope,element,attr) {
scope.callfunction = function() {
 /// your code
}
}
</directive>



केवल स्कोप का उपयोग करें। निर्देशक फ़ंक्शन को बुलाए गए फ़ंक्शन को जोड़ने के लिए $ पैरेंट

angular.module('myApp', [])
.controller('MyCtrl',['$scope',function($scope) {

}])
.directive('mydirective',function(){
 function link(scope, el, attr){
   //use scope.$parent to associate the function called to directive function
   scope.$parent.myfunction = function directivefunction(parameter){
     //do something
}
}
return {
        link: link,
        restrict: 'E'   
      };
});

एचटीएमएल में

<div ng-controller="MyCtrl">
    <mydirective></mydirective>
    <button ng-click="myfunction(parameter)">call()</button>
</div>



ओलिवर के उत्तर पर बिल्डिंग - आपको हमेशा निर्देशक के आंतरिक तरीकों तक पहुंचने की आवश्यकता नहीं होती है, और उन मामलों में आप शायद एक खाली वस्तु बनाना नहीं चाहते हैं और निर्देश को control एआरआर जोड़ना चाहते हैं ताकि इसे किसी त्रुटि को फेंकने से रोका जा सके ( cannot set property 'takeTablet' of undefined )।

आप भी निर्देश के भीतर अन्य स्थानों में विधि का उपयोग करना चाह सकते हैं।

मैं यह सुनिश्चित करने के लिए एक चेक scope.control कि scope.control मौजूद है, और प्रकट मॉड्यूल पैटर्न के समान तरीके से इसे सेट करें

app.directive('focusin', function factory() {
  return {
    restrict: 'E',
    replace: true,
    template: '<div>A:{{control}}</div>',
    scope: {
      control: '='
    },
    link : function (scope, element, attrs) {
      var takenTablets = 0;
      var takeTablet = function() {
        takenTablets += 1;  
      }

      if (scope.control) {
        scope.control = {
          takeTablet: takeTablet
        };
      }
    }
  };
});



पृष्ठ नियंत्रक में निर्देशक नियंत्रक कैसे प्राप्त करें:

  1. डीओएम तत्व से निर्देश नियंत्रक के संदर्भ प्राप्त करने के लिए एक कस्टम निर्देश लिखें:

    angular.module('myApp')
        .directive('controller', controller);
    
    controller.$inject = ['$parse'];
    
    function controller($parse) {
        var directive = {
            restrict: 'A',
            link: linkFunction
        };
        return directive;
    
        function linkFunction(scope, el, attrs) {
            var directiveName = attrs.$normalize(el.prop("tagName").toLowerCase());
            var directiveController = el.controller(directiveName);
    
            var model = $parse(attrs.controller);
            model.assign(scope, directiveController);
        }
    }
    
  2. पेज नियंत्रक के एचटीएमएल में इसका इस्तेमाल करें:

    <my-directive controller="vm.myDirectiveController"></my-directive>
    
  3. पेज नियंत्रक में निर्देश नियंत्रक का प्रयोग करें:

    vm.myDirectiveController.callSomeMethod();
    

नोट: दिया गया समाधान केवल तत्व निर्देशकों के नियंत्रकों के लिए काम करता है (टैग नाम वांछित निर्देश का नाम पाने के लिए उपयोग किया जाता है)।




Links