Utilizing Directives to Embed Attributes

My current challenge involves changing the fill color of attributes in an in-line SVG using Angular and TypeScript. The goal is to have the SVG elements with a "TA" attribute change their fill color based on a user-selected color from a dropdown menu. However, I am struggling to dynamically bind this attribute.

This is my approach:

export class TaDirective implements ng.IDirective {

static create_instance() : ng.IDirective {
    return new TaDirective();
}

constructor(){
}

public bindToController = true;
public controllerAs = "ctrl";
public scope = { name: '=' };

public compile(element: ng.IAugmentedJQuery, attrs: ng.IAttributes, transclude: ng.ITranscludeFunction) {
    var ta = attrs.$attr["ta"] as string

    var ele = element[0];
    attrs.$set('visibility', "visible")

    // Attempting to bind to the controller's fill
    attrs.$set('fill', "{{ ctrl.fill }}")
}

public link(scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes, controller: any, transclude: ng.ITranscludeFunction) {
}


public controller(scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes){
}

}
app.directive('ta', TaDirective.create_instance);

Check out the Plunker with the TypeScript and compiled JavaScript.

EDIT After some trial and error, I managed to make it work but it feels a bit clumsy as the scope name is hardcoded. Any suggestions on how to better separate the two would be appreciated. (Plunker also updated)

export class TaDirective implements ng.IDirective {
    static create_instance() : ng.IDirective {
        return new TaDirective();
    }

    constructor(){
    }

    public link(scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes, controller: any, transclude: ng.ITranscludeFunction) {
        var ta = attrs.$attr["ta"] as string

        var ele = element[0];

        attrs.$set('visibility', "visible")

        scope.$watch('vm.fill', function(newFill) {
            attrs.$set('fill', newFill)
        })
    }
}

Answer №1

One method commonly used to separate the controller from the directive watch expression is to monitor a specific attribute instead.

Rather than doing this:

JS:

scope.$watch('vm.fill', function (fill) {
    attrs.$set('fill', fill);
});

HTML:

<text ta="1">Text</text>

You could do this instead:

JS:

scope.$watch(attrs.ta, (fill: string): void => {
    attrs.$set('fill', fill);
});

HTML:

<text ta="vm.fill">Text</text>

This approach ensures that your directive can be more easily expanded since the watch expression for vm.fill is not tied to the directive link function, but is supplied to the directive via the angular template. Take a look at an updated plunkr here.

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

The AngularJs Wizard Validation Inputfield is unable to locate the scope

Hello all, I am new to AngularJs and encountering an issue with my code. Currently, my HTML structure looks like this: <div class="wizardContainer"> <wizard on-finish="finishedWizard()"> <wz-step title="1"> <h1>Questio ...

What is the best way to invoke a function in Typescript while retrieving data?

Is it possible to run a query in my main.ts file with another ts file and then pull the result of the query into another file? If so, how can this be achieved? Here is an example from my main.ts file: async function getAllTips() { const tips: any = []; ...

Having trouble fetching data using $http and promises in AngularJS

I'm having trouble connecting to my RESTful API within my AngularJS application. Despite my efforts, I'm not seeing any data being displayed on the screen. It seems like I might be misunderstanding the usage of $http with promises. Any suggestio ...

How to Extract the Specific Parameter Type from a Function in Typescript

After generating a client for an API using typescript-node, I encountered the following code: export declare class Api { getUser(username: string, email: string, idType: '1298' | '2309' | '7801') } I need to access the ...

Unlocking the power of global JavaScript variables within an Angular 2 component

Below, you will find a global JavaScript variable that is defined. Note that @Url is an ASP.Net MVC html helper and it will be converted to a string value: <script> var rootVar = '@Url.Action("Index","Home",new { Area = ""}, null)'; Sy ...

Is there a way to rotate a div without utilizing the "transform" CSS property?

I am currently utilizing a plugin from the SVG library to render graphics within a div (). However, I am encountering an issue when attempting to rotate it using the "transform" property. The rotation is purely visual and does not alter the X and Y axes of ...

Displaying error message on a MEAN stack web application

I'm pretty new to the MEAN stack and I must say, I'm learning a ton. Currently, my challenge is to display an error message on my page when a user is not authorized to access the website. On the page, there's a button that redirects you to t ...

Leveraging highchart SVG graphics in Selenium testing applications

Looking for some assistance with running a Selenium test in Java involving SVG high chart images on a webpage. The challenge I am facing is getting Selenium to recognize each element on the high chart and clicking on them to trigger another event. Below i ...

Modify capital letters to dashed format in the ToJSON method in Nest JS

I am working with a method that looks like this: @Entity() export class Picklist extends BaseD2CEntity { @ApiHideProperty() @PrimaryGeneratedColumn() id: number; @Column({ name: 'picklist_name' }) @IsString() @ApiProperty({ type: Str ...

Getting parameter names (or retrieving arguments as an object) within a method decorator in TypeScript: What you need to know

I am currently working on creating a method decorator that logs the method name, its arguments, and result after execution. However, I want to implement a filter that allows me to choose which parameters are logged. Since the number and names of parameter ...

Personalize the material design datatable checkbox option

Recently, I delved into the world of material-ui design in conjunction with ReactJS. However, I have encountered a roadblock while attempting to customize the style of a checkbox that is being displayed under the <TableRow /> component. (Check out th ...

AngularJS factory is not returning any valid data

My goal is to inject one geoDataFactory into venueDataFactory. However, when I log currentPosition to the console, it shows as undefined even though it should contain geolocation data like latitude and longitude. Why is this happening? angular.module(&apo ...

Organize data by month using angularjs

I'm working on an HTML page that displays a categorized list of data for each month. Here's a snippet of how the page looks: July, 2014: Monday 7th Data 7 Data 6 Friday 4th Data 5 Data 4 May, 2014: Sunday 15th Data 3 Thursday 8th Data ...

I am encountering an issue with CreateJS where I receive the error message: "createjs is not defined"

Looking for assistance with my createJS issue. var stage = new createjs.Stage(canvas); Encountering the following error : angular.js:13642 ReferenceError: createjs is not defined, even though I have EaselJS in my bower-components. Appreciate any hel ...

What is the best way to iterate through an array and dynamically output the values?

I am facing an issue with a function that retrieves values from an array, and I wish to dynamically return these values. const AvailableUserRoles = [ { label: 'Administrator', value: 1 }, { label: 'Count', value: ...

Angular JS appears to be causing the DOM to freeze up while utilizing the ng-repeat directive to loop through

I have a current app where clicking a button triggers an $http request to fetch and return some data. The retrieved information is then used to update the $scope variables rows and columns, which are then looped through using ng-repeat. However, I've ...

The concept of Nested TypeScript Map Value Type

Similar to Nested Typescript Map Type, this case involves nesting on the "value" side. Typescript Playground const mapObjectObject: Map<string, string | Map<string, string>> = new Map(Object.entries({ "a": "b", &quo ...

Can Chrome DevTools be used to manipulate the login process?

For a recent project, I utilized the login authentication logic from this GitHub repository as a reference: https://github.com/cornflourblue/angular-authentication-example In a situation where the backend was offline, I manually tweaked the frontend code ...

Displaying a dynamic menu using Angular's ngFor loop

I am attempting to create a menu with sub-menus. The desired structure for my menu is outlined below. However, the demo I'm testing is not producing the correct structure. Check out the demo here. "Sub Test": { // Main menu "Example1":"hai",//sub ...

Angular displaying a slice of the data array

After following the example mentioned here, and successfully receiving API data, I am facing an issue where only one field from the data array is displayed in the TypeScript component's HTML element. Below is the content of todo.component.ts file im ...