Transmit information from the main directive to the subordinate directive

Hi everyone, I have a quick question.. I'm working on a directive that includes an ng-repeat and transclude, with several child directives inside it that need to inherit specific objects from each iteration...

So far, I've only managed to achieve this by using scope.$parent.. but I'm not too keen on this approach because if the parent changes, the scope.$parent chain could get longer and messier...

My question is, how can I pass each iteration object to the children directives? I've tried using require and maybe $broadcast.. but haven't been successful in sending the specific iteration object...

<div demo-parent>
   <div demo-child1></div>
   <div demo-child2></div>
</div>

var demo = [obj1, obj2, obj3];

demo.directive('demoParent', [function() {
    return {
       scope: true,
       transclude: true,
       template: '<div ng-repeat="d in demo" ng-transclude></div>'
    ]
}]);

demo.directive('demoChild1', [function() {
    function link(scope, el, attr) {
         scope.someInfo = the specific info from parent; // now with scope.$parent.$parent.d
    }

    return {
       scope: true,
       transclude: true,
       template: '{{someInfo}}',
       link: link
    ]
}]);


demo.directive('demoChild2', [function() {
    function link(scope, el, attr) {
         scope.someInfo = the specific info from parent; // now with scope.$parent.$parent.d
    }

    return {
       scope: true,
       transclude: true,
       template: '{{someInfo}}',
       link: link
    ]
}]);

demoChild1 and demoChild2 are within demoParent in the markup but separate directives

Answer №1

There's a solution to tackle this issue rooted in transclusion scope and template scoping. I came across several insightful articles addressing this matter, such as here, here (an excellent resource), and here

In addition, I found a helpful discussion on SO question and answer at the bottom that deserves much credit. I simply adapted it for your situation.

Your inquiry involves using a child scope, but utilizing an isolated scope (which may be more secure) is also possible, and I'll demonstrate how.

Full disclosure: I'm not an AngularJS expert. My response might not be optimal or the most efficient. Your case is quite unconventional, so consider reviewing your approach (or share more details in your question for improved guidance)

Now onto the demonstration... For testing purposes, I streamlined your demo array, implemented a controller in the parent directive to define said array, and adjusted how my directives are declared.

HTML:

<body ng-app="soPOC">
    <div demo-parent>
        <div demo-child-one></div>
        <div demo-child-two></div>
    </div>

Module file defining root module:

(function () {
'use strict';
   angular.module('soPOC', []);
})();

Parent directive JS file defining the parent directive:

(function () {
'use strict';

angular.module('soPOC')
    .directive('demoParent', demoParent);

demoParent.$inject = ['$compile'];

function demoParent($compile) {
    var transclude;
    var template = '<div ng-repeat="item in demos"></div>';
    var directive = {
        restrict: 'EA',
        controller: controller,
        compile: compile
    };
    return directive;

    function compile(ele) {
        transclude = ele.html();
        ele.html('');

        return function (scope, elem) {
            var tpl = angular.element(template);
            tpl.append(transclude);
            $compile(tpl)(scope);
            elem.append(tpl);
        }
    }

    //deviating from your code
    controller.$inject = ['$scope'];
    function controller($scope) {
        //test array for demo items
        $scope.demos = ['test1', 'test2'];
    }
}

})();

Child directives JS file defining child directives one and two:

(function () {
'use strict';

angular
    .module('soPOC')
    .directive('demoChildOne', demoChildOne)
    .directive('demoChildTwo', demoChildTwo);

function demoChildOne() {
    var directive = {
        link: link,
        scope: true,
        restrict: 'EA',
        template: '<div>{{someInfo}}</div>'
    };
    return directive;

    function link(scope, element, attrs) {
        scope.someInfo = scope.item;
    }
}

function demoChildTwo() {
    var directive = {
        link: link,
        scope: true,
        restrict: 'EA',
        template: '<div>{{someInfo}}</div>'
    };
    return directive;

    function link(scope, element, attrs) {
        scope.someInfo = scope.item;
    }
}

})();

If you opt for an isolated scope style, you need to adjust your HTML accordingly by removing link functions from the child directives and making small syntax changes in those directives.

HTML:

<div demo-parent>
        <div demo-child-one item="item"></div>
        <div demo-child-two item="item"></div>
    </div>

Directive:

    function demoChildOne() {
    var directive = {
        scope: {
            item: '='
        },
        restrict: 'EA',
        template: '<div>{{item}}</div>'
    };
    return directive;
}

I recommend diving into the linked articles for deeper insights into why this solution works and gaining a better grasp of the scoping challenges with templates, transclusions, and directives. Hope this helps!

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

Error encountered when attempting to use Gridsome for Vue.js project construction

Currently, I am utilizing Vue.js and Gridsome to craft a personalized portfolio. However, an issue arose when I attempted to incorporate a JSON file to store my profile details on the site. Here is how I imported the file within my Index.vue component: &l ...

Integrate a character key feature to cycle through options in a customized Vue select component

In my Vue/Nuxt.js project, I have implemented a custom select component with arrow key functionality for scrolling through options and selecting with the enter key. Now, I am trying to add "jump key" functionality where pressing a character key will jump t ...

Ways to incorporate design elements for transitioning focus between different elements

When focusing on an element, I am using spatialNavigation with the following code: in index.html <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dfb5acf2acafbeabb6beb3f2b1bea9b6 ...

Chrome full screen mode can be toggled on websites after ajax data has loaded

I am currently experiencing a frustrating issue with Chrome on my webpage. The pagination feature loads content via an ajax call at: Whenever I click on the 2nd, 3rd, or subsequent tab in the pagination, the load process occurs but then suddenly jumps int ...

What is the process to insert a record into a table by triggering an AJAX call upon clicking "save

I'm looking to dynamically update a table with data from a database using AJAX. Specifically, I want the table to reflect any new records added by the user without having to refresh the entire page. Below is my JavaScript code snippet for handling thi ...

Is it possible to incorporate a fadein animation into a function?

Developing the entire HTML structure using JavaScript is one of my skills. Here is a snippet as an example: function generateHeader () { $('body').append( $('<header>') .attr('id', "main-header") ...

Can all browser console messages and errors be sent to a different machine using a pipeline?

Currently, I am in the process of troubleshooting a javascript error that is occurring within a Cordova app's InAppBrowser on an Android device. Despite being able to connect to the web-view on the phone using Chrome's remote debugging tools, the ...

Managing various events in AngularJSHandling multiple events in AngularJS

In my Angular application, I am updating a div when a tag is clicked. Now, I also need to change the route when the tag is clicked. How can I achieve this in AngularJS? ...

Is it possible to duplicate a div element and then make changes to both the original and the clone using a single button

I am dealing with an element that has three sub-elements element1, element2, and element3. When I press the button1 command, it filters element1. When I press the button2 command, it filters element2. How can I clone this element and manipulate both th ...

I'd like to change the name of the JSON key retrieved from the API request

I have a JSON format stored in my database that looks like this. [ { ip.src:"192.168.200.10", y:1506 }, { ip.src:"192.168.200.10", y:1506 }, { ip.src:"192.168.200.10", y:1506 }, { ip ...

react-leaflet LayerSelection creates redundant entries in table

Here is the React version I am using: 16.0.0 And for react-leaflet: 1.6.6 I recently attempted to implement a layer controller on my map which consists of two layers, each containing multiple markers. Below is an example of what I have been working on. i ...

Tips for showcasing a designated set of numbers in Vue Js while iterating?

Is there a way to specifically target numbers during a loop? For example, I only want to retrieve numbers 5 and above or within a certain range that I specify. <select name="" id="input" class="form-control" v-model="selectcompetitionyear"> < ...

Enhancing search results with data retrieved from a jSON response

At the moment, I am using a logic to generate a list of titles. Now, I would like to include data from the response along with the code for each title in the list. const title = responseData.map(item => { return { label: item.title, val ...

What is the best way to access the original observed node using MutationObserver when the subtree option is set to

Is there a way to access the original target node when using MutationObserver with options set to childList: true and subtree: true? According to the documentation on MDN, the target node changes to the mutated node during callbacks, but I want to always ...

Difficulty in constructing an array from several Firebase Storage URLs

I'm attempting to retrieve multiple image URLs and store them in an array using Firebase Storage. However, I am facing issues accessing specific index positions within the testArray: var testArray = [] listAll(ref).then((res) => { res.item ...

Navigational bar with React and Next.js. Issue: Hydration unsuccessful due to inconsistencies between the initial UI and the server-rendered content

I am working on a project with Next.js and React. I've created a navbar component but I keep encountering the following error message multiple times: Error: Hydration failed because the initial UI does not match what was rendered on the server. Warni ...

Flat list in React Native is not showing any items on the screen

Just checking in to see how you're doing I'm facing a strange issue with my react-native project. The FlatList items on some pages are not being displayed, even though I can see them when I console.log(json.items). Earlier today, everything was ...

Can someone provide guidance on how to send serialized data using a jQuery.getScript() request?

Is it feasible to make a request for an external JS file while simultaneously sending serialized data in that same request? I want to provide some values to validate the request, but without including those values in the request URL. Upon receiving the po ...

Executing a series of tests using Postman

Is running multiple requests in a postman script feasible? I have an endpoint: http://localhost/gadgets/{id}/buy This endpoint sets a flag in a gadget object/entry based on its id. With hundreds of gadgets, can I use a shared file of ids to create and run ...

Is Angular 4 failing to set headers properly or is Express.js searching in the wrong place?

When interacting with an Express.js API, I encountered a issue regarding the handling of auth tokens. The problem arose when sending the token in the request headers using Angular 4 compared to Postman. In Postman, setting the header named 'Authorizat ...