AngularJS: Modifying the parent scope from a controller inside an ng-switch

I've noticed that I can change a model value from a child controller, but when the child controller is inside an ng-switch, this functionality doesn't seem to work. Why is that? To illustrate this issue, I have created an example.

One workaround for this problem is to use the dot notation in the model name, such as bunnies.kills. Do you think this is a bug or just a feature of Angular? I'm using Angular 1.0.6.

Answer №1

To adapt your code structure for child controllers, you will need to modify the following:

$scope.$parent.kills++;

to

$scope.$parent.$parent.kills++;

Explanation: The scope of MainCtrl is the parent scope of SimpleParentCtrl, but it acts as the grandparent scope of Step1Ctrl and Step2Ctrl. It's important to note that when using ng-switch, a new scope is created, and then each instance of Step1Ctrl and Step2Ctrl generates a child scope within the ng-switch.

Note: Whenever the 1 or 2 button is clicked, both the ng-switch and its corresponding child controller receive a fresh scope.

Also: If you're curious about how the ng-switch directive establishes its own scope without a specific scope property, it manually creates a new scope in its link method using scope.$new(). Directives like ng-include, ng-switch, ng-repeat, and ng-view all create new scopes in a similar manner, either within the link method or through the returned function from the compile method.

Resources:

https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance http://www.youtube.com/watch?v=ZhfUv0spHCY&feature=youtu.be&t=30m

Answer №2

When utilizing ng-switch, a new child scope is generated, explaining why @sh0ber's solution is effective in this scenario. Typically, it is recommended that models be accessed within controller scopes (as reference objects) rather than as primitives. Therefore, employing a . notation is considered a "best practice".

This behavior should not be interpreted as a bug, nor should it be viewed as a feature. It simply reflects the workings of JavaScript prototypal inheritance with primitives.

Answer №3

In dealing with this issue, I propose a different approach.

Instead of relying on $scope.$parent, my suggestion is to centralize all bunny-killing logic within a shared service/model.

Addtionally, it's advisable to steer clear of referencing parent views/controllers. Doing so can complicate code reuse and debugging as the project scales. While a parent may have knowledge of its children, a child should have minimal awareness of its parent.

For an updated Plunk, please see: http://plnkr.co/edit/PLDbfU8Fu7m59A42qdR6?p=preview

HTML

<body ng-controller="MainCtrl">
    <p>
        Dead bunnies: <strong>{{Elmer.deadWabbits}}</strong>
    </p>
    <div ng-controller="SimpleParentCtrl">
        <button ng-click="Elmer.killTheWabbit()">Kill from simple parent gun</button>
    </div>
    <hr>
    <div ng-switch="" on="step">
        <div ng-switch-when="first" ng-controller="Step1Ctrl">
            <button ng-click="Elmer.killTheWabbit()">Kill from 1 tab gun</button>
        </div>
        <div ng-switch-when="second">
            <div ng-controller="Step2Ctrl">
                <button ng-click="Elmer.killTheWabbit()">Kill from 2 tab gun</button>
            </div>
        </div>
    </div>
    <hr>
    <p>
        <button ng-click="changeStep('first')">1</button> <button ng-click="changeStep('second')">2</button>
    </p>
</body>

JS

angular.module('plunker', []).
service("Elmer", [function() {
    this.deadWabbits = 0;
    this.killTheWabbit = function() {
        this.deadWabbits++;
    };
}]).
controller('MainCtrl', function($scope, Elmer) {
  $scope.Elmer = Elmer;
  $scope.step = 'first';
  $scope.changeStep = function(name){
    $scope.step = name;
  };
}).
controller('SimpleParentCtrl', function() {}).
controller('Step1Ctrl', function() {}).
controller('Step2Ctrl', function() {});

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

Leveraging the div id attribute in an HTML element

As a newcomer to front-end development, I am currently working with Angular Material. I am attempting to access a specific div element from a parent HTML file. Here is what I am trying to achieve: div.html <div id="myDiv"> <h1>My work in ...

What is the best way to extract specific values from a JSON array of objects using JavaScript?

I am facing some challenges in displaying values from the AJAX objects. My goal is to populate a select box with names using AJAX, but I seem to have made an error somewhere in my code. Can someone please assist me in identifying and correcting the mistake ...

There is an abundance of brief PHP documents

After conducting some initial research, I have realized that I need more information on the topic at hand. My interactive website relies on ajax calls to retrieve data from the server. Authenticated users engage with this data through various actions, whic ...

Sorting an array of strings based on user input using Vue.js

I'm facing an issue where I have an array of various strings: [ "Aluminum", "Basic Materials", "Broad Credit", "Broad Market", "Cocoa", "Coffee", "Consumer Cyclicals", "Consumer Non-cyclicals", "Copper", "Corn", "Cotton", "Crude Oil", "Energy", "Exte ...

Find the ID of the clicked table row using HTML and JavaScript

Currently, I am trying to implement this code snippet: <td align="center"> <div class="dropdown"> <button onclick="DropdownShow(this)" class="btn btn-default glyphicon glyphicon-picture"></button> <div id="@TableR ...

React Native encounters issues with removing the reference to the callback attribute upon unmounting

Utilizing a component that I place in an array (of various sizes) and controlling individual components through refs, while adding refs to an object to keep track of each separately. constructor(props){ super(props); this.stamps = []; this.get ...

Starting jQuery on embedded websites

I developed a platform that relies on JavaScript. Users of my platform are required to paste a code similar to Google Analytics, which automatically deploys a custom set of JavaScript functions along with the latest jQuery 1.9 through Google. The issue I ...

Utilizing AngularJS to display a table with Rowspan functionality and the ability to filter elements

I am trying to develop an HTML table that utilizes rowspan with ng-repeat to group data effectively. The overall layout is functioning as expected, but I encountered a problem when attempting to apply filters to the table. Specifically, when I filter the ...

Secure your Spring Sessions with Websocket and REST Token Security features

Our current setup includes a Spring application that features both a REST API and Websocket broker endpoints for receiving real-time updates on database changes. We recently completed the migration to the Spring Session project, incorporating an embedded ...

jQuery is optimized to work specifically with select id tags

Here is the HTML code snippet I've put together, along with my script. While I admit it might look a bit messy, please bear with me as I'm still in the learning phase. If anyone could offer some assistance on this matter, I would be extremely gra ...

Tips for populating a DOJO Select using JSON data that includes various parameters instead of just label and value

I am trying to populate a DOJO select element with JSON data where the item values for value are expressed by the code property. Here's an example of what I have: //require dojo Select var select = new Select({ name: "stateSelect", ...

Creating a list of identical elements with shared attribute values using nightwatch.js or JavaScript - a step-by-step guide

I have been using nightwatch.js for automating tests on a web application, and I am facing difficulties in creating a list of elements that share common values in their attributes. Below is an example: The first three spans with a common value for the att ...

Designing an architecture for a Java, Android, and database application - what will the final app's appearance be

I am currently working on a website where users need to complete tasks using an Android device: Fill out a simple HTML document. Sign the document on their Android device. Save the data entered into a database on the website. Some key points to consider ...

Having difficulty verifying the elements of an associative array after using json_decode

My goal is to implement form validation in PHP and send any errors to the AJAX call. I have structured the form inputs as an array with named indexes from the AJAX call to the PHP controller. Upon decoding it using json_decode() in PHP, my intention is to ...

In my React JS class component, I am looking to have the image display switch each time the button is clicked

How can I change the image when clicking a button in a class component? I am familiar with function components, but unsure how to achieve this. class CoffeeImages extends React.Component{ constructor(props){ super(props) ...

Is it possible to use WebRTC on mobile browsers without downloading a separate application?

Is there a webrtc demonstration that functions smoothly on a mobile browser without the need for a native OS App for android and iOS? I came across a demo on Mozilla Hacks where they were able to establish a connection through a webpage portal. They even ...

The implementation of pipelining for server-side processing

Initially, this function is set up to work with $_GET. However, after incorporating feedback from this discussion, I made adjustments to the function which resulted in an error message being displayed by Firebug. The error message reads: "json.aaData is ...

Alternative to updating object coordinates in Fabric JS 1.7.9 - seeking solutions for migration challenges

Update: JSFiddle: https://jsfiddle.net/Qanary/915fg6ka/ I am currently working on implementing the `curveText` function (found at the bottom of this post). It was functioning properly with `fabric.js 1.2.0`, but after updating to `fabric.js 1.7.9`, I not ...

Difficulty in altering the background of an input box

I am attempting to design a textbox that changes its background color to green when the correct answer is submitted, and to red for an incorrect answer. Unfortunately, nothing is happening for either option. document.querySelector('form').addE ...

Transforming the date format in VUE-JSON-EXCEL

Is there a way to change the date format for the VUE-JSON-EXCEL library? When I click the generate excel button, the date format displayed in the excel is "2022-06-10T18:18:34.000Z" instead of "10/6/2022 18:18:34" I have tried using moment.js but it is n ...