2013-04-13 17 views
66

में निर्देश से मूल नियंत्रक की कॉलिंग विधि मेरे पिछले question के बाद, अब मैं अपने निर्देश से मूल नियंत्रक पर एक विधि कॉल करने का प्रयास कर रहा हूं। मुझे एक अपरिभाषित पैरामीटर मिलता है। यहाँ मैं क्या करना है:एंगुलरजेएस

<body ng-app="myApp" ng-controller="MainCtrl"> 
    <span>{{mandat.rum}}</span> 
    <span>{{mandat.surname}}</span> 
<input type="text" ng-model="mandat.person.firstname" /> 
<my-directive mandate-person="mandat.person" updateparent="updatePerson()" > 

    </my-directive> 
</body> 

और स्क्रिप्ट:

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

    app.controller('MainCtrl', function ($scope) { 
     $scope.mandat = { name: "John", surname: "Doe", person: { id: 1408, firstname: "sam" } }; 
     $scope.updatePerson = function(person) { 
      alert(person.firstname); 
      $scope.mandat.person = person; 
     } 
    }); 


    app.directive('myDirective', function() { 
     return { 
      restrict: 'E', 
      template: "<div><span>{{mandatePerson.id}}<span><input type='text' ng-model='mandatePerson.firstname' /><button ng-click='updateparent({person: mandatePerson})'>click</button></div>", 
      replace: true, 
      scope: { mandatePerson: '=', updateparent: '&' } 
      } 
     } 
    ) 

जब updatePerson विधि कहा जाता हो जाता है, व्यक्ति अनिर्धारित रहता है। यहाँ

jsfiddle: http://jsfiddle.net/graphicsxp/Z5MBf/7/

उत्तर

54

बस सरल परिवर्तन के रूप में

नीचे
<my-directive mandate-person="mandat.person" updateparent="updatePerson(person)" > 

     </my-directive> 

आप updatePerson साथ "व्यक्ति" से गुजर रहा नहीं कर रहे हैं अपने html यही कारण है कि यह काम नहीं कर रहा

+0

तो मैं क्या कर रहा माता पिता गुंजाइश अद्यतन करने के लिए सही तरीका, सही है? मैं बस "व्यक्ति" पास करना भूल गया। – Sam

+0

अपने दाएं –

+4

किसी भी अन्य व्यक्ति के लिए जिसने शुरुआत में भ्रमित किया था: टेम्पलेट के भीतर एनजी-क्लिक में ऑब्जेक्ट नोटेशन देखें: 'ng-click = 'updateparent ({person: mandatePerson})' – ErikAGriffin

12

दो तरीके हैं, जिसके साथ हम & और = का उपयोग कर कॉल कर सकते हैं।

अगर मैं एक गुंजाइश विशेषता के लिए = का उपयोग कर रहा है, तो

ng-click='updateparent({person: mandatePerson})' 

ng-click='updateparent(mandatePerson)' 

करने और निर्देश में बदल जाएगा,

updateparent="updatePerson()" 

updateparent="updatePerson" 

तर्क यहाँ उल्लेख करने की आवश्यकता नहीं बदल जाएगा, वे एक संदर्भ के रूप में नियंत्रक के समारोह परिभाषा को दे दिया जाएगा।

& का उपयोग अन्य उत्तरों में समझाया गया है।

+1

धन्यवाद, '=' का उपयोग करके नियंत्रक की विधि '&' का उपयोग करने के साथ काम करना आसान है क्योंकि मुझे निर्देश उदाहरण –

+1

में सभी तर्क घोषित करने की आवश्यकता नहीं है, मैंने अभी एक पूरी दोपहर निर्देश को ठीक करने की कोशिश की है। समस्या निर्देश घोषणा में तर्क था (क्योंकि वे अस्तित्व में गए तर्क को अनिर्धारित किया गया था)। आपको बहुत बहुत धन्यवाद! –

37

नियंत्रक विधि तक पहुंचने का मतलब है निर्देशक नियंत्रक/लिंक/स्कोप से मूल दायरे पर एक विधि का उपयोग करना।

यदि निर्देश माता-पिता के दायरे को साझा/विरासत में ले रहा है तो यह केवल माता-पिता स्कोप विधि का आह्वान करने के लिए काफी आगे है।

पृथक निर्देश दायरे से अभिभावक स्कोप विधि तक पहुंचने के लिए थोड़ा और काम आवश्यक है।

कुछ विकल्प पृथक निर्देशों दायरे से एक माता पिता के दायरे विधि आह्वान या माता-पिता गुंजाइश चर (विकल्प # 6 विशेष रूप से) को देखने के लिए (नीचे सूचीबद्ध की तुलना में अधिक हो सकता है) कर रहे हैं।

नोट है कि मैं इन उदाहरणों में link function थे, लेकिन आप आवश्यकता के आधार पर के रूप में अच्छी तरह से एक directive controller उपयोग कर सकते हैं।

विकल्प # 1।वस्तु शाब्दिक और निर्देश एचटीएमएल टेम्पलेट से के माध्यम से

index.html

<!DOCTYPE html> 
<html ng-app="plunker"> 

    <head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script> 
    <script src="app.js"></script> 
    </head> 

    <body ng-controller="MainCtrl"> 
    <p>Hello {{name}}!</p> 

    <p> Directive Content</p> 
    <sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged(selectedItems)" items="items"> </sd-items-filter> 


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}} </p> 

    </body> 

</html> 

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" ng-change="selectedItemsChanged({selectedItems:selectedItems})" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'"> 
    <option>--</option> 
</select> 

app.js

var app = angular.module('plunker', []); 

app.directive('sdItemsFilter', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     items: '=', 
     selectedItems: '=', 
     selectedItemsChanged: '&' 
    }, 
    templateUrl: "itemfilterTemplate.html" 
    } 
}) 

app.controller('MainCtrl', function($scope) { 
    $scope.name = 'TARS'; 

    $scope.selectedItems = ["allItems"]; 

    $scope.selectedItemsChanged = function(selectedItems1) { 
    $scope.selectedItemsReturnedFromDirective = selectedItems1; 
    } 

    $scope.items = [{ 
    "id": "allItems", 
    "name": "All Items", 
    "order": 0 
    }, { 
    "id": "CaseItem", 
    "name": "Case Item", 
    "model": "PredefinedModel" 
    }, { 
    "id": "Application", 
    "name": "Application", 
    "model": "Bank" 
    }] 

}); 

काम कर plnkr: http://plnkr.co/edit/rgKUsYGDo9O3tewL6xgr?p=preview

विकल्प # 2। वस्तु शाब्दिक और निर्देश दिए गए लिंक से/गुंजाइश

index.html

<!DOCTYPE html> 
<html ng-app="plunker"> 

    <head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script> 
    <script src="app.js"></script> 
    </head> 

    <body ng-controller="MainCtrl"> 
    <p>Hello {{name}}!</p> 

    <p> Directive Content</p> 
    <sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged(selectedItems)" items="items"> </sd-items-filter> 


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}} </p> 

    </body> 

</html> 

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" 
ng-change="selectedItemsChangedDir()" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'"> 
    <option>--</option> 
</select> 

app.js

के माध्यम से

काम कर plnkr: http://plnkr.co/edit/BRvYm2SpSpBK9uxNIcTa?p=preview

विकल्प # 3। समारोह संदर्भ के माध्यम से और निर्देश एचटीएमएल टेम्पलेट से

index.html

<!DOCTYPE html> 
<html ng-app="plunker"> 

    <head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script> 
    <script src="app.js"></script> 
    </head> 

    <body ng-controller="MainCtrl"> 
    <p>Hello {{name}}!</p> 

    <p> Directive Content</p> 
    <sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged" items="items"> </sd-items-filter> 


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnFromDirective}} </p> 

    </body> 

</html> 

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" 
ng-change="selectedItemsChanged()(selectedItems)" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'"> 
    <option>--</option> 
</select> 

app.js

var app = angular.module('plunker', []); 

app.directive('sdItemsFilter', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     items: '=', 
     selectedItems:'=', 
     selectedItemsChanged: '&' 
    }, 
    templateUrl: "itemfilterTemplate.html" 
    } 
}) 

app.controller('MainCtrl', function($scope) { 
    $scope.name = 'TARS'; 

    $scope.selectedItems = ["allItems"]; 

    $scope.selectedItemsChanged = function(selectedItems1) { 
    $scope.selectedItemsReturnFromDirective = selectedItems1; 
    } 

    $scope.items = [{ 
    "id": "allItems", 
    "name": "All Items", 
    "order": 0 
    }, { 
    "id": "CaseItem", 
    "name": "Case Item", 
    "model": "PredefinedModel" 
    }, { 
    "id": "Application", 
    "name": "Application", 
    "model": "Bank" 
    }] 
}); 

काम कर plnkr: http://plnkr.co/edit/Jo6FcYfVXCCg3vH42BIz?p=preview

विकल्प # 4।समारोह संदर्भ के माध्यम से और के निर्देश दिए गए लिंक से/गुंजाइश

index.html

<!DOCTYPE html> 
<html ng-app="plunker"> 

    <head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script> 
    <script src="app.js"></script> 
    </head> 

    <body ng-controller="MainCtrl"> 
    <p>Hello {{name}}!</p> 

    <p> Directive Content</p> 
    <sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged" items="items"> </sd-items-filter> 


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}} </p> 

    </body> 

</html> 

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" ng-change="selectedItemsChangedDir()" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'"> 
    <option>--</option> 
</select> 

app.js

var app = angular.module('plunker', []); 

app.directive('sdItemsFilter', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     items: '=', 
     selectedItems: '=', 
     selectedItemsChanged: '&' 
    }, 
    templateUrl: "itemfilterTemplate.html", 
    link: function (scope, element, attrs){ 
     scope.selectedItemsChangedDir = function(){ 
     scope.selectedItemsChanged()(scope.selectedItems); 
     } 
    } 
    } 
}) 

app.controller('MainCtrl', function($scope) { 
    $scope.name = 'TARS'; 

    $scope.selectedItems = ["allItems"]; 

    $scope.selectedItemsChanged = function(selectedItems1) { 
    $scope.selectedItemsReturnedFromDirective = selectedItems1; 
    } 

    $scope.items = [{ 
    "id": "allItems", 
    "name": "All Items", 
    "order": 0 
    }, { 
    "id": "CaseItem", 
    "name": "Case Item", 
    "model": "PredefinedModel" 
    }, { 
    "id": "Application", 
    "name": "Application", 
    "model": "Bank" 
    }] 

}); 

काम कर plnkr: http://plnkr.co/edit/BSqx2J1yCY86IJwAnQF1?p=preview

विकल्प # 5: के माध्यम से एनजी-मॉडल और दो तरह से बाध्यकारी, आप माता-पिता गुंजाइश चर अद्यतन कर सकते हैं।। इसलिए, आपको कुछ मामलों में अभिभावक स्कोप फ़ंक्शन का आह्वान करने की आवश्यकता नहीं हो सकती है।

index.html

<!DOCTYPE html> 
<html ng-app="plunker"> 

    <head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script> 
    <script src="app.js"></script> 
    </head> 

    <body ng-controller="MainCtrl"> 
    <p>Hello {{name}}!</p> 

    <p> Directive Content</p> 
    <sd-items-filter ng-model="selectedItems" selected-items-changed="selectedItemsChanged" items="items"> </sd-items-filter> 


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItems}} </p> 

    </body> 

</html> 

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" 
ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'"> 
    <option>--</option> 
</select> 

app.js

var app = angular.module('plunker', []); 

app.directive('sdItemsFilter', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     items: '=', 
     selectedItems: '=ngModel' 
    }, 
    templateUrl: "itemfilterTemplate.html" 
    } 
}) 

app.controller('MainCtrl', function($scope) { 
    $scope.name = 'TARS'; 

    $scope.selectedItems = ["allItems"]; 

    $scope.items = [{ 
    "id": "allItems", 
    "name": "All Items", 
    "order": 0 
    }, { 
    "id": "CaseItem", 
    "name": "Case Item", 
    "model": "PredefinedModel" 
    }, { 
    "id": "Application", 
    "name": "Application", 
    "model": "Bank" 
    }] 
}); 

काम कर plnkr: http://plnkr.co/edit/hNui3xgzdTnfcdzljihY?p=preview

विकल्प # 6: $watch के माध्यम से और $watchCollection यह दो तरह से सब से ऊपर के उदाहरण में items के लिए बाध्यकारी, आइटम माता पिता दायरे में संशोधित कर रहे हैं, के निर्देश के आइटम भी बदलाव को प्रतिबिंबित होता है।

आप माता-पिता दायरे से अन्य विशेषताओं या वस्तुओं में देखना चाहते हैं, तो आप उस $watch और $watchCollection का उपयोग कर नीचे

एचटीएमएल दिए गए कर सकते हैं

<!DOCTYPE html> 
<html ng-app="plunker"> 

<head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script> 
    document.write('<base href="' + document.location + '" />'); 
    </script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script> 
    <script src="app.js"></script> 
</head> 

<body ng-controller="MainCtrl"> 
    <p>Hello {{user}}!</p> 
    <p>directive is watching name and current item</p> 
    <table> 
    <tr> 
     <td>Id:</td> 
     <td> 
     <input type="text" ng-model="id" /> 
     </td> 
    </tr> 
    <tr> 
     <td>Name:</td> 
     <td> 
     <input type="text" ng-model="name" /> 
     </td> 
    </tr> 
    <tr> 
     <td>Model:</td> 
     <td> 
     <input type="text" ng-model="model" /> 
     </td> 
    </tr> 
    </table> 

    <button style="margin-left:50px" type="buttun" ng-click="addItem()">Add Item</button> 

    <p>Directive Contents</p> 
    <sd-items-filter ng-model="selectedItems" current-item="currentItem" name="{{name}}" selected-items-changed="selectedItemsChanged" items="items"></sd-items-filter> 

    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItems}}</p> 
</body> 

</html> 

स्क्रिप्ट app.js

var app = angular.module('plunker', []); 

app.directive('sdItemsFilter', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     name: '@', 
     currentItem: '=', 
     items: '=', 
     selectedItems: '=ngModel' 
    }, 
    template: '<select ng-model="selectedItems" multiple="multiple" style="height: 140px; width: 250px;"' + 
     'ng-options="item.id as item.name group by item.model for item in items | orderBy:\'name\'">' + 
     '<option>--</option> </select>', 
    link: function(scope, element, attrs) { 
     scope.$watchCollection('currentItem', function() { 
     console.log(JSON.stringify(scope.currentItem)); 
     }); 
     scope.$watch('name', function() { 
     console.log(JSON.stringify(scope.name)); 
     }); 
    } 
    } 
}) 

app.controller('MainCtrl', function($scope) { 
    $scope.user = 'World'; 

    $scope.addItem = function() { 
    $scope.items.push({ 
     id: $scope.id, 
     name: $scope.name, 
     model: $scope.model 
    }); 
    $scope.currentItem = {}; 
    $scope.currentItem.id = $scope.id; 
    $scope.currentItem.name = $scope.name; 
    $scope.currentItem.model = $scope.model; 
    } 

    $scope.selectedItems = ["allItems"]; 

    $scope.items = [{ 
    "id": "allItems", 
    "name": "All Items", 
    "order": 0 
    }, { 
    "id": "CaseItem", 
    "name": "Case Item", 
    "model": "PredefinedModel" 
    }, { 
    "id": "Application", 
    "name": "Application", 
    "model": "Bank" 
    }] 
}); 

आप हमेशा रेफरी कर सकते हैं निर्देशों के बारे में विस्तृत स्पष्टीकरण के लिए एंगुलरजेएस दस्तावेज।

+0

यह 'लिंक' विधि में एक रैपर फ़ंक्शन बनाने में काम करता था। यह केवल एक समस्या थी जब मैंने एक निर्देश के भीतर से किसी अन्य निर्देश के दायरे को पारित किया। मूल अभिभावक नियंत्रक फ़ंक्शन को अभी भी बुलाया गया था लेकिन 'तर्क' को तब तक अपरिभाषित नहीं किया गया जब तक कि मैंने आपको सुझाव दिया था। – chovy

+0

मुझे सर्वर से एक fetch ट्रिगर करना पड़ा था, इसलिए लिंक फ़ंक्शन उदाहरण मेरे लिए वास्तव में अच्छा काम करता था क्योंकि मुझे डेटा को आगे और आगे भी पास नहीं करना था, बस AJAX फ़ंक्शन को कॉल करें। इस तरह के एक सटीक और अच्छी तरह से जवाब देने के लिए आप 3 वोटों के लायक हैं। –

1

यहां एक और पैटर्न है (कोणीय 1.5 में काम करता है)।

angular.module('module', []) 
 

 
    .controller('MyController', function() { 
 

 
     var self = this; 
 
     self.msg = 0; 
 
     // implement directive event listener interface 
 
     this.onEvent = function(arg) { 
 
      self.msg++; 
 
     }; 
 
    }) 
 

 
    .directive('myDirective', function() { 
 
     return { 
 
      scope: { 
 
      data: '=', 
 
      handler: '=' 
 
      }, 
 
      template: '<button ng-click="handler.onEvent(data)">Emit event</button>' 
 
     } 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script> 
 

 

 
<div ng-app="module" ng-controller="MyController as ctrl"> 
 
<my-directive handler="ctrl" data="'...received'"></my-directive> 
 
    {{ctrl.msg}} 
 
</div>