如何在动态添加的span标签中调用AngularJS控制器方法?
Hey there, let's figure out how to get this working properly. The core issue with your current code is two-fold:
- You're using vanilla JavaScript to inject HTML directly via
innerHTML, which AngularJS doesn't automatically compile—so youronclickhandler can't connect to your$scope.demoMethod. - Your onclick syntax has errors (missing quotes around the jQuery selector, and trying to call a scope method directly on a DOM element, which isn't how Angular works).
Here are the best ways to fix this:
1. Use AngularJS's $compile Service (Recommended)
Angular provides the $compile service to process dynamic HTML and bind it to your controller's scope. This is the proper Angular way to handle dynamic DOM elements.
Step-by-Step Implementation:
First, inject $compile into your controller, then use it to compile your dynamic HTML before adding it to the DOM:
// Your controller definition (make sure to inject $compile) app.controller('YourController', ['$scope', '$compile', function($scope, $compile) { $scope.demoMethod = function() { console.log("it works"); }; // Assume your children array is defined here const children = ['Item 1', 'Item 2', 'Item 3']; // Get the target element using Angular's element wrapper const fileDisplay = angular.element(document.getElementById('FileDisplay')); // Loop through your children array to create elements children.forEach(child => { // Create the HTML string with ng-click (not onclick!) const dynamicHtml = `<span ng-click="demoMethod()"></span>${child}<br>`; // Compile the HTML against your controller's scope const compiledElement = $compile(dynamicHtml)($scope); // Append the compiled element to the DOM fileDisplay.append(compiledElement); }); }]);
Why This Works:
$compileprocesses the HTML, bindsng-clickto your$scope.demoMethod, and ensures Angular recognizes the new element.- Using
ng-clickinstead of vanillaonclickaligns with Angular's data-binding patterns.
2. Avoid Dynamic DOM Altogether (Even Better!)
If possible, use Angular's built-in directives like ng-repeat to generate your elements instead of manual DOM manipulation. This is the most "Angular-native" approach:
<!-- In your HTML --> <div id="FileDisplay" ng-controller="YourController"> <span ng-click="demoMethod()"></span>{{child}}<br> </div>
// In your controller app.controller('YourController', ['$scope', function($scope) { $scope.demoMethod = function() { console.log("it works"); }; // Define your children array here $scope.children = ['Item 1', 'Item 2', 'Item 3']; }]);
This way, Angular handles all DOM generation and binding automatically—no need for manual innerHTML or $compile calls.
3. Quick (Not Recommended) Fix with Vanilla JS
If you absolutely have to use vanilla JS to inject the HTML (we don't recommend this, as it breaks Angular's data flow), you can grab the controller's scope directly and call the method:
// Get the scope associated with the FileDisplay element const scope = angular.element(document.getElementById('FileDisplay')).scope(); // Inject the HTML with a corrected onclick handler document.getElementById("FileDisplay").innerHTML += `<span onclick="scope.demoMethod()"></span>${children[i]}<br>`;
Caveats:
- This relies on accessing the scope directly, which is against Angular's best practices.
- It won't work if your controller uses an isolated scope, and can cause issues if the scope is destroyed or updated.
内容的提问来源于stack exchange,提问作者Shridhar Chini

