AngularJS डायरेक्टिव एलिमेंट मेथड बाइंडिंग - TypeError: 'functionName' को खोजने के लिए 'ऑपरेटर' में 'का उपयोग नहीं कर सकता'


90

यह मुख्य टेम्पलेट का नियंत्रक है:

app.controller('OverviewCtrl', ['$scope', '$location', '$routeParams', 'websiteService', 'helperService', function($scope, $location, $routeParams, websiteService, helperService) {
    ...     
    $scope.editWebsite = function(id) {
        $location.path('/websites/edit/' + id);
    };
}]);

यह निर्देश है:

app.directive('wdaWebsitesOverview', function() {
    return {
        restrict: 'E',
        scope: {
            heading: '=',
            websites: '=',
            editWebsite: '&'
        },
        templateUrl: 'views/websites-overview.html'
    }
});

इस तरह से निर्देश मुख्य टेम्पलेट में लागू किया जाता है:

<wda-websites-overview heading="'All websites'" websites="websites" edit-website="editWebsite(id)"></wda-websites-overview>

और यह विधि निर्देशात्मक टेम्पलेट (वेबसाइट-ओवरव्यू.html) से ली गई है:

<td data-ng-click="editWebsite(website.id)">EDIT</td>

प्रश्न: जब EDIT पर क्लिक किया जाता है, तो यह त्रुटि कंसोल में दिखाई देती है:

TypeError: 1 में 'editWebsite' खोजने के लिए 'ऑपरेटर' का उपयोग नहीं कर सकता

क्या किसी को पता है कि यहां क्या होता है?

जवाबों:


178

चूंकि आपने एक अभिव्यक्ति बाइंडिंग ( &) को परिभाषित किया है , इसलिए आपको इसे JSON के साथ स्पष्ट रूप से कॉल करने की आवश्यकता है, idयदि आप इसे HTML में बांधना चाहते हैं edit-website="editWebsite(id)"

वास्तव में, कोणीय को यह समझने की आवश्यकता है कि यह idआपके HTML में क्या है, और चूंकि यह आपके दायरे का हिस्सा नहीं है, इसलिए आपको अपनी कॉल में "स्थानीय" कहे जाने वाले शब्दों को जोड़ने की आवश्यकता है:

data-ng-click="editWebsite({id: website.id})"

या एक विकल्प के रूप में:

data-ng-click="onClick(website.id)"

नियंत्रक / लिंक कोड के साथ:

$scope.onClick = function(id) {
  // Ad "id" to the locals of "editWebsite" 
  $scope.editWebsite({id: id});
}

यह यहाँ प्रलेखित है, इसमें शामिल उदाहरण देखें "close({message: 'closing for now'})"

https://docs.angularjs.org/guide/directive


7
आपके उत्तर के लिए और प्रलेखन पर सटीक स्थान बताने के लिए धन्यवाद, यह अविश्वसनीय मददगार था!
ब्रूनो बेलोटी

1
@floribon मुझे पता है कि यह पुराना है, लेकिन क्या आपके पास कॉलबैक टाइप करने का एक उदाहरण है?
tcrite

यह वास्तव में उपयोगी है, धन्यवाद।
अनुराग पारीक

विरासत परियोजनाओं पर काम करने वाले लोगों के लिए अभी भी उपयोगी है .. धन्यवाद
बीएमडब्ल्यूसीएमडब्ल्यू

4

टी एल; डॉ; - आप मान रहे हैं कि बाध्य घटक बाल घटक को पारित किया जा रहा है। यह गलत है। वास्तव में, AngularJS स्ट्रिंग टेम्पलेट को पार्स कर रहा है और एक नया फ़ंक्शन बना रहा है, जो तब मूल फ़ंक्शन को कॉल करता है।

इस फ़ंक्शन को एक सादे चर के बजाय, चाबियाँ और मूल्यों के साथ एक वस्तु प्राप्त करने की आवश्यकता है।

लम्बी व्याख्या

ऐसा तब होता है जब आपने 'और' का उपयोग करके किसी फ़ंक्शन को बाध्य किया है, और अपने नियंत्रक से उस फ़ंक्शन को कॉल करने का प्रयास किया है, जो सादे चर के नाम वाले ऑब्जेक्ट के बजाय एक सादे चर को पार कर रहा है। ऑब्जेक्ट कुंजी को टेम्प्लेटिंग इंजन द्वारा वर्कआउट करने के लिए आवश्यक है कि मानों को बाध्य फ़ंक्शन में कैसे पास किया जाए।

जैसे। तुमने boundFunction('cats')बजाय बुलाया हैboundFunction({value: 'cats'})

काम किया उदाहरण

कहो मैं इस तरह एक घटक बनाने के लिए:

const MyComponent = {
  bindings: {
    onSearch: '&'
  },
  controller: controller
};

यह फ़ंक्शन (पैरेंट में) इस तरह दिखता है:

onSearch(value) {
  // do search
}

अपने मूल टेम्पलेट में, अब मैं यह कर सकता हूं:

<my-component on-search="onSearch(value)"></my-component>

यहाँ बंधन स्ट्रिंग से पार्स किया जाएगा। आप वास्तव में फ़ंक्शन पास नहीं कर रहे हैं। AngularJS आपके लिए एक फ़ंक्शन बना रहा है जो फ़ंक्शन को कॉल करता है। टेम्प्लेट में बनाई गई बाइंडिंग में फ़ंक्शन कॉल के अलावा बहुत सी चीजें हो सकती हैं।

AngularJS को किसी तरह से वर्कआउट करने की आवश्यकता होती है, जहां से प्राप्त करना valueहै, और यह माता-पिता से एक वस्तु प्राप्त करके करता है।

MyComponent कंट्रोलर में, मुझे कुछ करने की आवश्यकता है:

handleOnSearch(value) {
  if (this.onSearch) {
    this.onSearch({value: value})
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.