AngularJS问题:HTML传递的$index在控制器方法中显示undefined
Let's walk through why you're seeing undefined for the index parameter and how to fix it step by step:
First, the critical method name mismatch
Looking at your code, you're calling vm.updateAssociatedPayorAgreement(item, $index) in the HTML, but your controller defines updatePayorAgreement(selectedAgreement, index). The method names don't match! This is a key issue—your callback isn't pointing to the right function, which directly contributes to the undefined parameter problem.
Second, the scope conflict with $index
AngularJS's md-autocomplete creates its own child scope. When you reference $index directly in md-selected-item-change, you're trying to access it from the autocomplete's scope, not the parent ng-repeat scope where $index actually exists. That's why it's coming back as undefined.
Step-by-Step Fixes
1. Align the method names
Either update the HTML to use the controller's method name, or rename the controller function to match the HTML. Let's rename the controller function to match the HTML call:
// Rename the function to match what's in your HTML function updateAssociatedPayorAgreement(selectedAgreement, index) { console.log(selectedAgreement); console.log(index); // This will now log the correct index if (selectedAgreement && selectedAgreement._id && selectedAgreement.name) { $timeout(function () { vm.diagnosiscoverage[index].payoragreement = { _id: selectedAgreement._id, name: selectedAgreement.name }; vm.diagnosiscoverage[index].payoragreement = selectedAgreement._id; }, 100); } }; // Don't forget to attach it to your view model! vm.updateAssociatedPayorAgreement = updateAssociatedPayorAgreement;
2. Pass the correct index from the ng-repeat scope
You have two reliable ways to get the right $index into your callback:
Option A: Use $parent.$index
Since the autocomplete's scope is a child of the ng-repeat scope, you can explicitly reference the parent scope's $index:
md-selected-item-change="vm.updateAssociatedPayorAgreement(item, $parent.$index)"
Option B: Use ng-init to store the index (more explicit)
Add ng-init to your ng-repeat container to save the current index in a variable that's accessible to the autocomplete:
<div layout-gt-xs="row" layout="column" ng-repeat="agreement in vm.payor.associatedpayoragreements" ng-init="currentIdx = $index"> <md-autocomplete id="PYRDetailAscPayAgr{{currentIdx}}" <!-- ... rest of your autocomplete attributes ... --> md-selected-item-change="vm.updateAssociatedPayorAgreement(item, currentIdx)" <!-- ... rest of your autocomplete content ... --> > </md-autocomplete> </div>
This approach avoids scope inheritance confusion and makes your code more readable.
Full Corrected Code Snippets
Updated HTML
<div class="md-dialog-content"> <md-dialog-content ng-keydown="vm.error = '';"> <div layout-gt-xs="row" layout="column" ng-repeat="agreement in vm.payor.associatedpayoragreements" ng-init="currentIdx = $index"> <!-- Payor Agreement --> <md-autocomplete id="PYRDetailAscPayAgr{{currentIdx}}" md-require-match="true" class="md-block" md-input-name="autocompleteField1" required md-min-length="2" md-no-cache="true" md-search-text="payorAgreementSearcher" md-selected-item="vm.payor.associatedpayoragreements[currentIdx].payoragreementuid.name" title="{{vm.payor.associatedpayoragreements[currentIdx].payoragreementuid.name}}" md-items="item in vm.queryPayorAgreement(payorAgreementSearcher, currentIdx)" md-item-text="item.name" md-selected-item-change="vm.updateAssociatedPayorAgreement(item, currentIdx)" md-floating-label="{{'MENU.BILLINGCONFIGURATION.PAYORAGREEMENT' | translate}}" flex="100" > <md-item-template> <span md-highlight-text="payorAgreementSearcher">{{ '(' + item.code + ') ' + item.name }}</span> <md-tooltip>{{'(' + item.code + ') ' +item.name }}</md-tooltip> </md-item-template> <md-not-found> <span translate>ERRORS.NOMATCHES</span> </md-not-found> </md-autocomplete> </div> </md-dialog-content> </div>
Updated Controller JS
function updateAssociatedPayorAgreement(selectedAgreement, index) { console.log(selectedAgreement); console.log(index); // Now correctly logs the index from ng-repeat if (selectedAgreement && selectedAgreement._id && selectedAgreement.name) { $timeout(function () { vm.diagnosiscoverage[index].payoragreement = { _id: selectedAgreement._id, name: selectedAgreement.name }; vm.diagnosiscoverage[index].payoragreement = selectedAgreement._id; }, 100); } }; vm.updateAssociatedPayorAgreement = updateAssociatedPayorAgreement;
内容的提问来源于stack exchange,提问作者Raghul

