如何仅在AngularJS UI Bootstrap手风琴展开时调用函数
Got it, the issue with your current setup is that load_userdata runs every time you click the accordion heading—even when you're closing the panel, not just opening it. Let's fix that by leveraging the accordion group's built-in is-open property to trigger the function only when the panel expands.
Here's how to adjust your code:
Step 1: Update the HTML Template
Bind each accordion group's open state to a property on the user object, and use ng-change to trigger a check when the state toggles:
<uib-accordion close-others="oneAtATime"> <div uib-accordion-group class="panel-default" ng-repeat="user in users" is-open="user.isOpen" ng-change="handleAccordionToggle(user)"> <uib-accordion-heading> <div class="table"> <div style="width: 50%"> @{{user.name}} </div> <div> Load user data </div> </div> </uib-accordion-heading> <!-- Add your user data display here once loaded --> <div ng-if="user.data"> <!-- Example user data display --> <p>Email: @{{user.data.email}}</p> <p>Phone: @{{user.data.phone}}</p> </div> </div> </uib-accordion>
Step 2: Adjust the Controller Logic
Add a handler function that only loads data when the panel is opening, and store the loaded data on the user object to avoid duplicate calls if the panel is toggled closed then re-opened:
$scope.load_userdata = function(user_id) { console.log('Loading data for user:', user_id); // Replace with your actual API call to fetch user data /* $http.get('/api/users/' + user_id) .then(function(response) { const user = $scope.users.find(u => u.id === user_id); if (user) { user.data = response.data; } }) .catch(function(error) { console.error('Error loading user data:', error); }); */ }; $scope.handleAccordionToggle = function(user) { // Only load data if the panel is opening AND data hasn't been loaded yet if (user.isOpen && !user.data) { $scope.load_userdata(user.id); } };
Key Improvements:
- Targeted trigger: The function only runs when the panel transitions to an open state, not on every heading click.
- Prevents duplicate requests: We check for existing
user.dataso we don't re-fetch data if the panel is re-opened later. - Cleaner structure: Removes the
ng-clickfrom the heading, which was causing unintended function calls.
If you prefer a more concise approach without the separate handler, you can put the condition directly in ng-change:
<div uib-accordion-group class="panel-default" ng-repeat="user in users" is-open="user.isOpen" ng-change="user.isOpen && !user.data && load_userdata(user.id)">
This achieves the same result without adding an extra function to the controller.
内容的提问来源于stack exchange,提问作者krishna ganisetti

