AngularJS controller function fails to trigger

I have three directives, "parenta", "parentb", and "childb". The first two are siblings while the third one is a direct child of "parentb".

When attempting to call a controller method from "parenta", it does not work. Strangely, calling a method on the "childb" controller FROM "parenta" seems to be working instead. What could be causing this unexpected behavior?

var app = angular.module("app", []);

app.directive("parenta", function () {
    return {
        template: "<section><div ng-click='vm.a()'>Rendered by a</div></section>",
        replace: false,
        controllerAs: "vm",
        controller: function () {
            this.a = function () {
                console.log("Function A called!");
            }
        }
    }
})

app.directive("parentb", function () {
    return {
        template: "<childb></childb>",
        replace: false
    }
})

app.directive("childb", function () {
    return {
        template: "<section><div ng-click='vm.b()'>Rendered by b</div></section>",
        replace: false,
        controllerAs: "vm",
        controller: function () {
            this.b = function () {
                console.log("Function B called!");
            }
        }
    }
})

HTML:

<div ng-app="app">
    <parenta></parenta>
    <parentb></parentb>
</div>

View Codepen Example: http://codepen.io/anon/pen/pJMpVe

Answer №1

The main issue lies in the fact that your directives do not establish a child or isolate scope, and instead utilize scope: false (the default setting).

This results in every directive, along with its aliased controller, creating a shared scope property named vm - all within the same scope. As a result, childb ends up overwriting the vm property initially set by parenta.

You can easily verify this - simply change one of the controllerAs aliases to something different.

A simple solution - and the correct approach - is to use either scope: true or scope: {}.

Answer №2

Instead of using a controller, I opted to utilize the link function.

In AngularJS, directive controllers facilitate inter-directive communication, while link functions are contained within and specific to the directive instance. Interdirective communication refers to when one directive on an element needs to communicate with another directive on its parent or the same element. This interaction may involve sharing state, variables, or even functions.

In the code below, I have commented out the controller function and integrated the link function

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">

</head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>

<script type="text/javascript">

var mod = angular.module("app", []);

mod.directive("parenta", function () {
    return {
        /*template: "<section><div ng-click='vm.a()'>Rendered by a</div></section>",*/
        template: "<section><div ng-click='a()'>Rendered by a</div></section>",
        replace: false,
        link: function($scope,$element,$attrs)
        {
        $scope.a = function()
        {        
                console.log("a called!");
        }
        }        
       /* controllerAs: "vm",
        controller: function () {
            this.a = function () {
            alert("a called!");
                console.log("a called!");
                
            }
        }        
        */
    }
})

mod.directive("parentb", function () {
    return {
        template: "<childb></childb>",
        replace: false
    }
})

mod.directive("childb", function () {
    return {
        template: "<section><div ng-click='vm.b()'>Rendered by b</div></section>",
        replace: false,
        controllerAs: "vm",
        controller: function () {
            this.b = function () {            
            console.log("b called!");
            }
        }
    }
})

</script>


<body>

<div ng-app="app">
    <parenta></parenta>
    <parentb></parentb>
</div>

</body>
</html>

Alternatively, if utilizing a controller directive, it is advisable to implement Directive Isolate Scopes.

Unlike a controller which pairs with a newly created scope upon creation, a directive does not automatically receive its own scope. Instead, it uses the available scope based on its DOM location.

An isolate scope denotes giving the directive its private scope that does not inherit from the existing scope.

Therefore, we can use

scope: true in our parenta

mod.directive("parenta", function () {
    return {             
    template: "<section><div ng-click='vm.a()'>Rendered by a</div></section>", 
 replace: false,
 scope: true , // Isolate scope
 
 controllerAs: "vm",
 controller: function () {
     this.a = function () {            
         console.log("a called!");
         
     }
 }   

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

Uh oh! The dreaded Error [ERR_HTTP_HEADERS_SENT] has struck again in the Node Express MongoDB world. Headers cannot be set after they have

Hey there, newbie in the coding world! I've been diving into a guide on setting up a backend server using Node.js, Express, and MongoDB. You can find the guide here: But I seem to keep running into an error when testing with Postman. Error [ERR_HTTP ...

Issues with data binding in Angular2 are arising specifically in IE11

After successfully loading the application on Chrome, Firefox, and Edge, I encountered difficulties when trying to load it on IE11. The data bindings were not created properly, despite the internal data being fetched correctly through a websocket connectio ...

Is there a method in TypeScript to make an enum more dynamic by parameterizing it?

I've defined this enum in our codebase. enum EventDesc { EVENT1 = 'event 1', EVENT2 = 'event 2', EVENT3 = 'event 3' } The backend has EVENT1, EVENT2, EVENT3 as event types. On the UI, we display event 1, event 2, a ...

What is the best way to add external javascript files to bookmarklets?

I have been developing a CDN for a collection of scripts that I created for my job. Previously, I had to distribute these scripts individually and each user would have to download and install them on their own computer. Now, I am transitioning them to an A ...

Three.js not rendering any objects, only displaying a blank black screen

I've encountered a similar issue with a few of my other three.js codes. I've set up the JavaScript within HTML, but the objects aren't appearing on the screen. Every time I run the file, it just shows a black screen. The file is supposed to ...

Is there a way to retrieve the id of every post on my page?

Is it possible to send multiple post ids in JavaScript? I have successfully sent the first post id, but now I need to figure out how to send each individual post id. When inspecting the elements, I see something like this: <div data-id="post_1">< ...

Combining selected boxes through merging

Looking to create a simple webpage with the following requirements: There should be 10 rows and 3 boxes in each row. If I select 2 or more boxes or drag a box, they should merge together. For example, if my initial screen looks like this: and then I se ...

Loading a .css file in advance using NextJS

We have integrated NextJS and Material-UI into our website, but we are facing an issue with FOUC (Flash of Unstyled Content) upon page loading. After some investigation, I discovered that the JS files are loading faster than the CSS file, causing the probl ...

Update the var value based on the specific image being switched using jQuery

I have implemented a jQuery function that successfully swaps images when clicked. However, I am now looking to enhance this functionality by passing a parameter using $.get depending on the image being displayed. Here is the scenario: I have multiple comm ...

Issue with AngularJS form not binding to $http request

<form novalidate class="form-horizontal"> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <div class="text-capitalize"> </ ...

Tips for simulating or monitoring a function call from a separate file

Within my codebase, there is a function that is triggered upon submission. After the payload has been posted, I aim to execute a function located in a distinct file named showResponseMessage: Contact.js import { onValueChangeHandler, showResponseMessage, ...

Tips for creating JavaScript validation for the Amount input field (in the format 22.00) in an ASP.NET application

In this aspx page using ASP.NET 4.0, there is a text box where users can enter a rate. The requirement is that only numbers are allowed to be entered. For example, if the user enters 22, it should display as 22.00. If the user enters 22.5, it should displa ...

Issue with webcomponents-lite.js file

Encountering this particular error message in the console while attempting to run the application: webcomponents-lite.js:64Uncaught TypeError: Cannot read property 'getAttribute' of null at webcomponents-lite.js:64 at Object.549 (webcomp ...

The flow of browsing the web and executing scripts in a web browser

I'm really struggling to grasp the logic behind this function I'm working on. public void PortalLogin(AutoResetEvent signal) { // Navigate to portal string portalUrl = "website_name"; ...

Error: The property '...' is not found in the ReactElement<any, any> type, but it is required in the type '{...}'

As a beginner in TypeScript, I am currently working on rendering a page by fetching data from getStaticProps. The code snippet I am using for this purpose is: import React, {FormEvent, useState} from "react"; import { InferGetStaticPropsType } fr ...

The issue with Google Maps not functioning properly at 100vh has been identified specifically on Android app

#map-canvas {height: 100vh; width: 100vw;} <ion-view title="Truck Map"> <ion-nav-buttons side="left"> <button menu-toggle="left" class="button button-icon icon ion-navicon"></button> </ion-nav-buttons> < ...

What is the best way to compile an array of permissible values for a specific CSS property?

One interesting aspect of the CSS cursor property is its array of allowed values, ranging from url to grabbing. My goal is to compile all these values (excluding url) into an array in JavaScript. The real question is: how do I achieve this without hardco ...

Customize form input using Javascript prior to inserting into database

On my Rails form, I have a basic setup like the following: <%= form_for @song do |f| %> <p> <%= f.label :url %><br> <%= f.text_field :url %> </p> <p> <%= f.submit %> </p> <% en ...

Numerous slide bars within a single HTML document

As I continue learning how to code, I've encountered an issue with my website project. I'm trying to incorporate multiple image sliders, but only the first one is functioning properly. The images on the other sliders are not displaying. I suspect ...