`Why is AngularJS ng-click not firing after attempting to compile?`

I am working on a directive with a template that includes a scope variable named content:

<div class="directive-view">
    <span class="directive-header">My Directive</span>
    <span ng-bind-html="content"></span>
</div>

In the following directive, I have set up a watch for changes to the content variable and then compile the element's contents:

(function () {
    "use strict";

    angular
        .module('myApp.myDirective', [])
        .directive("myDirective", myDirective);

    function myDirective($compile, $sce) {
        return {
            restrict: 'E',
            scope: {
            },
            templateUrl:'../partials/directives/my-directive.html',
            controller: function($scope) {
                $scope.testAlert = function(msg) { alert(msg) };
            },
            link: function (scope, element, attrs, ctrl) {

                scope.content = $sce.trustAsHtml('Initial value');

                scope.$watch(attrs.content, function(value) {
                    element.html(value);
                    console.log("Content changed -- recompiling");
                    $compile(element.contents())(scope);
                });

                scope.content = $sce.trustAsHtml('<button ng-click="testAlert(\'clicked!\')">Click</button>');
            }
        };
    }
})();

Although the directive renders the button element, the testAlert() function in the controller is not called when the button is clicked.

Furthermore, the callback for $watch only triggers once after setting content to 'Initial value'. It does not trigger again after changing content to the button. I expected the callback to be triggered when attrs.content changes its value.

Even after manually recompiling the element:

$compile(element.contents())(scope);

The testAlert function still does not get executed when clicking on the button element.

How can I ensure that the element's contents are correctly recompiled so that the bindings work as intended?

Answer №1

Instead of using $sce in this scenario, simply utilize $compile.

Check out a live demo on jsfiddle.

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

myApp.controller('MyCtrl', function($scope) {
    $scope.name = 'Superhero';
$scope.changeTEmplate = function(){
      $scope.cont = '<div><b>i\'m changed</b></div>';
    }
  })
  .directive("myDirective", function myDirective($compile) {
    return {
      restrict: 'E',
      scope: {content:"="},
      template: `<div class="directive-view">
    <span class="directive-header">My Directive</span>
    <span></span>
    </div>`,
      controller: function($scope) {
        $scope.testAlert = function(msg) {
          alert(msg)
        };
      },
      link: function(scope, element, attrs, ctrl) {
        scope.$watch('content', function(value) {
          var span = angular.element(element.find('span')[1]);
          span.html(value);
          console.log("Content changed -- recompiling",value);
            $compile(span)(scope);
        });
        scope.content = '<button ng-click="testAlert(\'clicked!\')">Click</button>';
      }
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="MyCtrl">
    Hello, {{name}}!
    <button ng-click="changeTEmplate()"> change Content</button>
    <my-directive content="cont"></my-directive>
  </div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Experiencing the error message "Unable to access property 'innerHTML' of null" despite initializing the corresponding ID

After doing some research, I discovered that this issue usually arises when the specific div is not loaded yet or simply does not exist. My code is set to loop continuously, ensuring that even if it wasn't fully loaded the first time, it will be by th ...

How can I hide selected options in GraphQL playground?

I'm facing an issue in the playground with my view. When I try to add another option to select, pressing CTRL + space shows me every possible option, including the ones already selected. Is there a way to prevent this behavior? I only want to see the ...

Explore the jQuery feature that allows you to hover over text

I'm facing an issue that has got me a bit stuck on how to resolve it. Currently, when hovering over this specific image, the opacity decreases (exposing a background color) and text appears. However, I want this effect to persist even when hovering o ...

What is the best way to trigger a filter function that has been stored in a variable?

I need assistance with executing a filter function stored in a variable when the user clicks a button. The function enableFilter must compare item.id with item.category and trigger the filter if they match. Can someone provide guidance on how to achieve ...

After the rendering process, the React Component member goes back to a state of

One issue I encountered is related to a component that utilizes a separate client for making HTTP requests. Specifically, when trying to use the client within a click event handler, the call to this.client.getChannel() fails due to this.client being undefi ...

The popup is unable to remain in the center of the screen because the background page keeps scrolling back to the top

Whenever I click a button to open a popup window, the page unexpectedly scrolls to the top. It's frustrating because if I'm at the bottom of the page and press the 'submit' button, the popup doesn't display in the center as intende ...

JQUERY is unable to recognize the property or method 'menu' for this object

How can I create a menu using an existing UL from a large HTML file called index.html? Here is the code snippet: <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>jQuery UI Menu - Default functionality< ...

Customizing Sphere Hues Individually in three.js

Within my scene, a unique arrangement of 7 spheres creates a flower petal formation. The setup includes 6 spheres around the perimeter and one sphere at the center. I aimed to randomize the color of each sphere individually. Below is the code snippet utili ...

Next.js configuration: Redirecting / to the basePath

Whenever a user accesses the path /, I need it to redirect to the basePath that has been previously set. Below is my configuration in next.config.js: module.exports = { basePath: '/docs', } This means that whenever the path / is visited, it s ...

Click the button to insert a time stamp into the text area

Whenever the id=dodaj_godzine_button is clicked, I would like to add the current time to id=formularz_wpis_tresc (as a string). I attempted to do this using the code below, but it seems to be malfunctioning. $("#dodaj_godzine_button").click(function(){ ...

Resize a group of images to match the parent's width and height dimensions

I am working with a div that contains variously-sized images and is nested inside a parent container. <div id="parentContainer"> <div id="boxToScale"> <img src="http://placehold.it/350x150" /> <img src="http://placehold.it/150 ...

Having trouble selecting all checkboxes in the tree using angular2-tree when it first initializes

My goal is to have all checkboxes auto-checked when clicking the "feed data" button, along with loading the data tree. I've attempted using the following code snippet: this.treeComp.treeModel.doForAll((node: TreeNode) => node.setIsSelected(true)); ...

Encountering an "Unmet Peer Dependency" error message while attempting to integrate bootstrap-ui into my Angular project

Currently, my goal is to successfully install angular-ui. Following the tutorials, I have attempted all commands such as: npm install angular-bootstrap However, this command results in an error message: +-- UNMET PEER DEPENDENCY angular@>=1.5 After ...

Using footable js will eliminate all form elements within the table

After incorporating the Footable jQuery library to create a responsive table, I encountered an issue with input tags and select boxes being removed by the Footable JavaScript. It turns all these tags into empty <td> elements. <table id="accordi ...

Using VueJS for Dynamic Class Binding

Using Vue version 3.0.5. I have a component named Cube.vue where I am attempting to dynamically assign a blue or green class to a child element. The component has been created and imported into a specific page, however, I am facing issues getting the con ...

`Having trouble with importing the react-redux module in next.js due to an error with the <Provider/&

Encountered the following error in Next.js browser and terminal: SyntaxError: Cannot use import statement outside a module import Provider from './components/Provider'; ^^^^^^ SyntaxError: Cannot use import statement outside a module at Obj ...

Upgrade to iOS 8 and experience the new Full Screen Mode feature. When you tap on a text field for the first time, the onscreen keyboard will flash briefly

Recently, I encountered a strange issue with my web app (AngularJS HTML5) after upgrading my iPad to iOS8. The onscreen keyboard started acting strangely - when I tapped a text field once, the keyboard would very briefly flash and then disappear. It was so ...

Retrieve a single instance of every element within an array using JavaScript

I have an array of player objects, each containing properties such as "position" and "player_name". With 8 unique positions available for players, I aim to extract the first player for each position and transfer them to a new array. This way, the new array ...

Firefox not rendering responsive YouTube embed properly

This method of embedding seems to be functioning well on all browsers except for Firefox; I took advantage of a free trial at crossbrowsertesting.com to verify. I’m not using a direct iFrame embed, and all the solutions I’ve come across are related to ...

how can I retrieve an element using a datetime in JavaScript

I have a list of appointments like the one below: 0: {start: '2022-02-23T09:30:00', end: '2022-02-23T10:00:00',…} 1: {start: '2022-02-23T10:00:00', end: '2022-02-23T10:30:00',…} 2: {start: '2022-02-2 ...