Top strategy for reaching a directive's controller

The directive known as "form aka ngForm" can be accessed using the form name.

<form name="testForm"> </form>

In the controller, we can use it like this:

$scope.testForm.$valid 

And in HTML:

<button ng-show="testForm.$valid>

This turns the "form" directive into a UI component with accessible properties and methods (similar to non-HTML world)

Is there a standard approach to achieve such componentization for custom directives? For instance, I would like to create a directive called "list" with methods like "selectElement", "scrollToTop", "scrollToElement", "doSomething" etc. and utilize it in this way:

<list name="myList></list>

<button ng-click="myList.doSomething()">

and in another controller:

$scope.myList.scrollToTop();

I created a simple workaround based on what the "form" directive does - it exposes the public API of the directive in the scope under the variable defined by the name attribute:

app.directive('list', function () {
        return {
            restrict: 'E',
            controller: function ($scope, $element, $attrs) {

                // check if component name doesn't conflict with scope
                if ($attrs.name) {
                    if (angular.isDefined($scope[$attrs.name])) {
                        throw "Error, component already defined with name: " + $attrs.name;
                    } else {

                      // publish controller object as public API

                      scope[$attrs.name] = {
                               date: new Date(), 
                               myFunction: function(){}
                      };
                    }
                }
            },
            template: '<ul></ul>'
        }
    });

Therefore:

<list name="myList"></list>
<button ng-click="myList.myFunction()">

and

$scope.myList.myFunction();

However, this does not work with isolated scope directives - a workaround could be passing the API object as an attribute with two-way binding as discussed in this question: How to call a method defined in an AngularJS directive?.

I also considered defining the API in a service, but it seems cumbersome - the service has to somehow be linked to the correct DOM element of the directive.

So my query is - what is the optimal pattern for accessing directive methods and properties from both HTML and other controllers to truly make directives act as UI components?

Or a simpler question - how can we access directive controllers from another controller or another expression in HTML similar to how we can do it with directives via "require"?

Answer №1

Even when a scope is isolated, it still contains the $parent property which references the parent scope. So in response to your query, a potential solution could be as follows:

angular.module('example', []).directive("bar", function() {
  return {
    controller: function($scope, $element, $attrs) {
      $scope.$parent[$attrs.bar] = this;
      this.methodName = function() {
          // ...
      };
    },
    scope: {},
    restrict: 'A'
  };
});

Give it a try on Plunker: http://plnkr.co/edit/zyXbQP?p=preview

Answer №2

Utilizing directive controller with the use of controllerAs is recommended. For more information, you can view this resource.

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 .each function in JavaScript is creating conflicts with other classes on the webpage

HTML <ul class="courseDates"> <li class="dateOne col-sm-2"> {tag_course date 1} </li> <li class="dateTwo col-sm-2"> {tag_course date 2} </li> <li class="dateThree col-sm-2"> { ...

In order for the Facebook share button to appear, a page reload is required when using Angular

I've been working on integrating Facebook's share plugin, but I've encountered an issue where the share button only shows up after reloading the page. If I navigate to the page through a link or URL, the button doesn't appear until afte ...

Learn the method to duplicate Outer HTML with the use of jQuery or Pure JavaScript

I have successfully copied the value of an input into the clipboard using the first part of the solution provided. However, I am now trying to figure out how to copy HTML content like an entire <p> tag. Currently, when attempting this, I am encounter ...

Why is php $_REQUEST returning an empty array for certain files when using AngularJS for uploading?

Here is the code snippet that I am currently working with: Upload.upload({ url: "/ajaxHandler_importBaProds.php", data: { file: $scope.file, catId: $scope.catId, submit: 'upload ...

Selecting a specific element from a group of elements sharing the same class using JQuery

Is there a way to target individual elements from a group of elements that share the same classes or other properties without assigning different classes to each element? I need to be able to work on each element separately. I have attempted this approach, ...

Steps for making a webpack-bundled function accessible globally

I am currently working with a webpack-bundled TypeScript file that contains a function I need to access from the global scope. Here is an example of the code: // bundled.ts import * as Excel from 'exceljs'; import { saveAs } from 'file-save ...

Simultaneous click targeting for both elements in a mat-checkbox

There is a single mat-checkbox element that is used in the mobile version as well. The issue arises when there are two separate sections, one for desktop and one for mobile. The desktop version of <mat-checkbox> functions correctly with select and u ...

What is preventing TypeScript from recognizing enums in libraries?

Check out the TypeScript types defined for html-validator: declare namespace HtmlValidator { // ... enum ValidationResultsOutputFormats { json = 'json', html = 'html', xhtml = 'xhtml', ...

Seeking a breakdown of fundamental Typescript/Javascript and RxJs code

Trying to make sense of rxjs has been a challenge for me, especially when looking at these specific lines of code: const dispatcher = fn => (...args) => appState.next(fn(...args)); const actionX = dispatcher(data =>({type: 'X', data})); ...

Experience the power of VueJS 3 with Pinia, all without the need

I've hit a wall. Despite scouring documentation and countless google searches, I can't seem to find the answer to this straightforward query: how do I install/import PINIA in a VUE application? Let's consider a basic VUE app: <div id=&qu ...

Assign the value from the list to a variable in order to execute an API call

Imagine a scenario where there's a button that displays a random joke based on a specific category. The categories are fetched using an API request from https://api.chucknorris.io/jokes/categories The jokes are generated from https://api.chucknorris. ...

Determine whether the request was made using ajax or traditional non-ajax methods

While testing the PHP code below, I noticed that the headers in the request do not indicate that it is JavaScript sending the request instead of a non-JavaScript user: Accept:*/* Accept-Encoding:gzip,deflate,sdch Accept-Language:en-US,en;q=0.8 AlexaToolba ...

Adding elements to a list using the appendChild method

Hey there! I have a bunch of images and I'm trying to create a navigation list item for each image. Here's the code I currently have: var bigImages = $('#imagesList li img'); // grabs the Big Images Next, I've set up a ul with t ...

Order of operations in angularjs tasks

Imagine having two run functions within an app: angular.module('example',[]) .run(function(){ console.log('second'); }) .run(function(){ console.log('first'); }); Can runs be executed based on priority? ...

Resolving Unrecognized Vue Variable in PhpStorm

I'm encountering an issue with my Vue script in PhpStorm. Despite setting the variable redirect_to, I am getting an Unresolved variable syntax error during debugging. Please refer to the image below for further information. How can I resolve this prob ...

``Is it feasible to extract a PDF file using a PDF viewer in selenium using C# programming language

Facing an issue with downloading PDF files using JavaScriptExecutor: I am trying to automate the process of downloading a PDF file in a new window using JavaScriptExecutor. The online PDF viewer window has a toolbar section with options like print and d ...

Creating a JSON object using JavaScript for sending to a PHP script

I'm working on a form that contains radio buttons as options. To send the selected radio button values to a PHP script, I need to construct a JSON object for posting. Although I've attempted to create the necessary code, I'm uncertain about ...

Using TypeScript, what is the best way to call a public method within a wrapped Component?

Currently, I'm engaged in a React project that utilizes TypeScript. Within the project, there is an integration of the react-select component into another customized component. The custom wrapped component code is as follows: import * as React from " ...

Tips for avoiding JavaScript Client-Side DOM Code Injection Vulnerabilities

Line xxx in the addAnnouncements.js file contains a method function that retrieves data from the client-side for a json element. This data is then used in client-side code without proper sanitization or validation, and is ultimately incorporated into the H ...

Transforming Nested JavaScript Objects for Internationalization in Vue

In my VUE JS web application that utilizes i18n-vue, I am facing an issue with reformatting a JS Object to work with the i18n-vue setup. The translations are retrieved from the database and are structured in a certain way as shown below. I have tried seve ...