Sending ng-* attributes to an Angular component

I have a custom Angular directive called <my-button> where I want to run another directive (my-fun-directive) on its output. To achieve this, I am using $compile instead of a directive template. However, it seems that using this method does not allow me to pass additional HTML attributes or ng-* attributes.

Custom Directive

app.directive('myButton', function ($compile) {
    return {
        restrict: 'E',
        replace: true,
        scope: true,
        link: function (scope, element, attrs) {
            var btnTxt = attrs.text || "";
            scope.buttonInnerHtml = attrs.icon ? '<span class="glyphicon glyphicon-' + attrs.icon + '"></span> ' + btnTxt : btnTxt;
            var template = '<button type="button" class="myCustomClass" ng-bind-html="buttonInnerHtml" my-fun-directive></button>';

            var content = $compile(template)(scope);
            element.replaceWith(content);
        }
    };
});

Usage Example

<my-button
    icon="ok"
    text="Save Changes"
    class="anotherClass"
    ng-hide="someProperty"
    ng-click="myClickEvent()"
    example-directive></my-button>

Current Output (line breaks added for readability)

<button
    type="button"
    class="myCustomClass"
    ng-bind-html="buttonInnerHtml"
    my-fun-directive>
        <span class="glyphicon glyphicon-ok"><span> Save Changes
</button>

Desired Output (line breaks added for readability)

<button
    type="button"
    class="myCustomClass anotherClass"
    ng-bind-html="buttonInnerHtml"
    ng-hide="someProperty"
    ng-click="myClickEvent()"
    my-fun-directive
    example-directive>
        <span class="glyphicon glyphicon-ok"><span> Save Changes
</button>

In the desired output, notice the inclusion of ng-* attributes, an additional directive, and an added CSS class. How can I ensure that all these elements work together seamlessly?

Answer №1

The issue arose from the HTML content within buttonInnerHtml. I encountered an error message stating "Attempting to use an unsafe value in a safe context." After addressing this problem, everything functioned correctly:

<!doctype html>
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.js"></script>
    </head>
    <body ng-app="plunker" ng-controller="MainCtrl">
        <my-button
            icon="check"
            text="Submit Form"
            class="customClass"
            ng-hide="isHiddenProperty"
            ng-click="handleClickEvent()"
            sample-directive></my-button>
    </body>
    <script>
    var app = angular.module('plunker', []).directive('myButton', function ($compile, $sce) {
        return {
            restrict: 'E',
            replace: true,
            scope: true,
            link: function (scope, element, attrs) {
                var buttonText = attrs.text || "";
                scope.buttonInnerHtml = attrs.icon ? '<span class="glyphicon glyphicon-' + attrs.icon + '"></span> ' + buttonText : buttonText;
                scope.buttonInnerHtml = $sce.trustAsHtml(scope.buttonInnerHtml);
                var template = '<button type="button" class="customBtnClass" ng-bind-html="buttonInnerHtml" custom-fun-directive></button>';

                var content = $compile(template)(scope);
                element.replaceWith(content);
            }
        };
    }).controller('MainCtrl', ['$scope', '$http', function($scope, $http) {

    }]);
    </script>
</html>

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

When attempting to perform $save() on $resource, a TypeError is thrown indicating that Object #<g> does not contain the method 'push'

Resource factory: .factory('WorkerRepository', function($resource){ return $resource('workers/:id', {id:'@id'}); }) Controller: .controller('ListController', function($scope, WorkerRepository){ var workers ...

Making dynamically loaded elements respond to mouse events

I'm facing an issue with a simple mouseover event that I am trying to implement on elements loaded via ajax. Specifically, I have a div where mousing over it should show/hide another div. However, when I load these divs through ajax, the functionality ...

The standard flow of work in ReactJS

Exploring the world of ReactJS for the first time has been an exciting journey. I am diving into the basic workflow of this library, along with React Router, without involving Redux. While the learning curve is relatively fast, I find myself encountering c ...

Do I need to utilize getStaticProps along with JSON imports in Next.js?

Is it necessary to use getStaticProps in order to render static data from a JSON or typescript file, or can the data be imported without using getStaticProps? The documentation I read didn't provide a clear answer. projects.tsx const projects: [ { ...

Avoid inputting numbers and special characters

In my coding work, I have crafted a function that detects the key pressed by the user through an event. NameValidation(e){ if(!e.key.match(/^[a-zA-Z]*$/)) { e.key = ''; console.log(e.key); } }, This function essentia ...

Caution: Potential risk of non-deterministic routing - Trying to generate page: [...] that already exists

Recently, I completed the development of a small blog application using Gatsby and React. The application functions perfectly when tested locally on my machine. However, upon deploying the build folder to Netlify, I encountered an issue where some pages fa ...

Unable to access an Express Route

While working on my ExpressJS route, everything was running smoothly until I introduced a new route, causing me to encounter the error message: Cannot GET /api/users/abc This error appeared when using Postman. Displayed below are images illustrating the ...

Executing jQuery code after a data update in Angular can be achieved by utilizing

Currently, I am working with Angular 1.4.7 on a site that was not set up by me. As a result, I am uncertain about the specific information needed in this scenario. We are displaying search filters, but their enabling or disabling is controlled by data fetc ...

How can I convert an Array into a Dictionary using JavaScript?

Is there a clever method (perhaps using a map function) to restructure my data object from this: [ {id: 1, from: "1/1/2021", to: "1/2/2022"}, {id: 2, from: "1/3/2021", to: "1/4/2022"}, {id: 1, from: "1/5/2 ...

Unusual behavior observed within for loop; code within not running as expected

I will be presenting my code along with some images to illustrate the issue at hand. Something as simple as declaring a variable or using the log function results in the json being undefined. Upon entering text into the input field, the ajax call is trigg ...

Creating a ROT13 cipher in JavaScript

In my JS function, I need to handle a variable called i. My goal is to encode this variable using ROT13 before proceeding with the function. The challenge lies in decoding the variable and integrating it into the script. I came across a JavaScript implem ...

Errors related to missing RxJS operators are occurring in the browser, but are not showing up in Visual Studio

Recently, I encountered a peculiar problem with my Angular4 project, which is managed under Angular-CLI and utilizes the RxJS library. Upon updating the RxJS library to version 5.5.2, the project started experiencing issues with Observable operators. The s ...

Execute location.replace when the "control" key is pressed

document.addEventListener('keydown', (event) => { var name = event.key; var code = event.code; if (name === 'Control') { location.replace(classroom.google.com) } if (event.ctrlKey) { alert(`Combinatio ...

AngularJS HTTP GET request failed to load the specified URL

I am working on a simple Angular code to read JSON data from a specific API URL. When I access the URL , it returns the following JSON data: Although the URL works fine when accessed through a browser, I'm facing issues while trying to read the same ...

Injecting CSS styles into the head tag dynamically with jQuery from within the body of a

When it comes to adding CSS to the head of an HTML page from the body using JavaScript and jQuery, I have come across two methods. One involves using jQuery to directly append the CSS to the head, while the other method involves creating a style element an ...

Unable to utilize React Router component

Having some trouble creating a React router structure in my React JS app. The problem is with using the react-router element. I have a component called Main Page that I want to display after the page has loaded, along with a nav component that should be di ...

The VueJS app seems to be experiencing difficulties with rendering the content

Just starting out with VueJS and I have my initial files - index.html and index.js. I want to stick with just these two files and not add any more. Here's the content of index.html: <html lang="en"> <head> <meta charset ...

Filtering a collection using another collection in Backbone: tips and tricks

I am managing two distinct collections: Collection X includes element1, element2, element3, element4. Collection Y consists of element2, element3. For illustration purposes: var element1 = new models.ExModel({id: "1", name: "element1"}); var elemen ...

Using $watch to monitor the existence of a variable within the AngularJS scope

I'm working on a directive that displays alerts, and I want to set up a timeout function to run whenever the 'show' variable changes. How can I achieve this? When I tried invoking the link function, all the variables - show, message, and ty ...

Executing Angular directive when ng-change event occurs

I'm encountering an issue with my angular-bootstrap modal popup box that includes a custom directive in the template: Modal.html <div class="modal-header"> <h3 class="modal-title">Modal Header</h3> </div> <div class="m ...