Is there a way for me to extract a sub-object from a larger object, utilize it as the data for multiple instances of a single controller, and ensure that all instances remain synchronized?

Sorry for any confusion in the question :-P

I am working with a single JavaScript object that contains all the data for my application. I have a controller that will be used multiple times throughout the app, all working with the same data added through a service.

For a read-only/edit mode interaction, I create two copies of the original data source in the service. Users manipulate the data in edit mode, and can save it to read-only mode by pressing a button (using angular.copy).

Additionally, I want the controller instances to work on specific parts of the data source, not the entire thing.

The issue I'm experiencing is that when I press the button to perform angular.copy, it seems to reassign the variable instead of updating the value it was pointing to.

Code below and a jsfiddle link can be found here: http://jsfiddle.net/q5ca5quq/1/

<html ng-app='app'>
<body>

    <div ng-controller='a_controller as ctrl_1'>
        read_mode_inner = {{ ctrl_1.read_mode_inner }}<br>
        edit_mode_inner = {{ ctrl_1.edit_mode_inner }}<br>
        <br>
        <input ng-model='ctrl_1.edit_mode_inner[0].a'>
    </div>    
    <br><br><br>
    <div ng-controller='a_controller as ctrl_2'>
        read_mode_inner = {{ ctrl_2.read_mode_inner }}<br>
        edit_mode_inner = {{ ctrl_2.edit_mode_inner }}<br>
        <br>
        Change this and press button below <input ng-model='ctrl_2.edit_mode_inner[0].a'> <br>
        <button ng-click='ctrl_2.change()'>Copy edit_mode_inner into read_mode_inner</button>
    </div>





<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js'></script>
<script type='text/javascript'>

    angular.module('app',[])
    .factory('DataService', [function() {
        data = {
            xx : [{'a':1}, {'b':2}, {'c':3}],
            yy : [{'a':1}, {'b':2}, {'c':3}]
        }

        return {
            read_mode : data,
            edit_mode : angular.copy(data)
        }
    }])
    .controller('a_controller', ['DataService', function(DataService) {
        var self = this;
        window.s = self; // For debugging

        self.read_mode = DataService.read_mode;
        self.edit_mode = DataService.edit_mode;

        self.read_mode_inner = self.read_mode.xx;
        self.edit_mode_inner = self.edit_mode.xx;

        self.change = function(){
            self.read_mode_inner = angular.copy(self.edit_mode_inner);
        }

    }]);


</script>
</body>
</html>

Answer №1

http://jsfiddle.net/q5ca5quq/2/

If you want to share data between controllers using a service and ensure that all controller instances update whenever the value in the service changes, you can implement $watch within your controller:

$scope.change = function(){
    DataService.read_mode.xx = angular.copy($scope.edit_mode_inner);
}

$scope.$watch(function(){return DataService}, function(dataService){
    $scope.read_mode_inner = dataService.read_mode.xx;
}, true);

To make this work, make sure to use angular $scope instead of this/self reference. By using $scope, you can simplify angular notation in HTML. You don't need to name controllers separately:

Instead of:

<div ng-controller='a_controller as ctrl_1'>
    read_mode_inner = {{ ctrl_1.read_mode_inner }}<br>
    edit_mode_inner = {{ ctrl_1.edit_mode_inner }}<br>
</div>

You can simply use:

<div ng-controller='a_controller'>
    read_mode_inner = {{ read_mode_inner }}<br>
    edit_mode_inner = {{ edit_mode_inner }}<br>
</div>

With $scope handling the rest of the updates.

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

"Enhancing user experience with dynamic input fields through Ajax auto-fill functionality

I have a unique invoice form that allows users to add multiple parts at their discretion. As the user inputs a part number, an AJAX script automatically populates the description and price fields. The script functions properly for the initial input fields ...

Transferring shapes from a two-dimensional equirectangular view to surfaces in A-Frame

Currently, my goal is to create a hotspot editor for 360-degree images using A-Frame. The concept behind this project involves allowing users to draw on an equirectangular panorama and then having the tool convert those drawings into planes using THREE.Sh ...

We apologize, but Google Pay encountered an unexpected developer error that caused the request to fail. Please try again later

When attempting to make a payment using Google Pay on a real device in the TEST environment, I am encountering the error mentioned in the title. I have followed the guidance provided in the Google docs and tried converting 'gateway' to a string, ...

Switch Background Image - The image failed to display

Here is the code snippet I am currently working with. It involves displaying a background-image when clicking on a link with the class 'home-link', and not showing an image if the link does not have this class. The issue at hand: The problem ari ...

Navigating through JQuery

Is there a way to scroll to a div + 100px specifically on the y axis? I am unsure how to achieve this. Can you provide guidance? I attempted using $.scrollTo('div100' + '100px', 2000) but unfortunately, it did not produce the desired ...

What is the best way to tailor specific text in d3.js?

I need assistance with customizing the appearance of an asterisk added to the end of a template literal in d3js. I want to be able to independently adjust the size and color of the asterisk regardless of the variable it's attached to. Below is the cod ...

Incorporate JavaScript values into an HTML form to submit them to PHP

How can I successfully POST the values of 'vkey' and 'gene+varient' when submitting a form in HTML? The values are retrieved using JS code and displayed correctly on the form, but are not being sent upon submission. <form action="ac ...

Using Multithreading and the Subscribe/Publish Methodology in JavaScript

Is it true that JavaScript does not support multithreading? I am seeking expert advice on a specific scenario. I need to make an AJAX call and upon successful completion, trigger a set of events to update different parts of the UI simultaneously. Would ...

Update button text in real-time using JavaScript

I am currently working on a dropdown list that contains 5 elements displayed inside a button when pressed. I want the button to show a default text "Filter by:" before displaying the selected tab value. Additionally, I need the caret symbol to be visible. ...

What is the best way to organize a json based on numerical values?

Can anyone guide me through sorting a JSON data into an array based on numeric value, and then explain how to efficiently access that information? {"362439239671087109":{"coins":19},"178538363954003968":{"coins":18},"234255082345070592":{"coins":137}} Th ...

The fixed left div and scrollable right div are experiencing issues with their alignment

I am having an issue with a section where the left div is fixed and the right div is scrollable. However, the content of the right div scrolls even before the scroll top reaches the section. My goal is for the right div to scroll only when it reaches the t ...

What is the best way to combine an array into a single string and insert it into a textarea with line breaks?

My current goal involves executing the following code with no success: var arr = ['one', 'two','three'] const mydiv = document.createElement('textarea') mydiv.innerText = arr.join('\r\n') docum ...

What is the best way to implement JavaScript for loading and removing content based on button clicks on a webpage?

I'm in need of a vanilla JavaScript solution (I know JQuery options exist, but I want to stick to vanilla JS for now)? Currently, I am using a simple page as a testing ground for my ongoing project. The page consists of two buttons that load HTML pag ...

Solving the checkbox toggle challenge with recursive functions | Recursive checkbox challenge

I'm currently working on creating a checkbox tree with the following data structure for items const checkboxes = [{ field: 'ARTICLE', id: 41, name: 'Article', parentId: null, checked: false, children: [ ...

What is the best way to add data to a URL in an ActionResult Method using window.location.href?

I am having trouble understanding how to retrieve data using window.location.href = '/Product/Success/'+data.OrderTrackNo+'';. I am able to get data using ajax, but it seems different when retrieving data with window.location.href, whic ...

Guide to successfully passing a function as a prop to a child component and invoking it within Vue

Is it really not recommended to pass a function as a prop to a child component in Vue? If I were to attempt this, how could I achieve it? Here is my current approach: Within my child component - <template> <b-card :style="{'overflow-y&apo ...

Ways to calculate the total of two arrays

One of my recent challenges involved creating a calculator using JavaScript. The main issue I encountered was figuring out how to find the sum of 2 arrays. The first number, 33, is saved to an array called num1, and the second number, 99, is saved to an a ...

Is there a way to continuously switch a CSS animation class without needing a second click?

I am seeking a solution to animate the color and size of a div box, then return it to its original state when a button is clicked. Here is an example of my code: document.getElementById("andAction").addEventListener("click", function() { document.getE ...

Assigning null values, or initializing values in AngularJS

How can I clear input values to null after clicking on a button? Empty fields: https://i.sstatic.net/JDTZA.jpg Fields with existing values that I want to reset back to empty fields. https://i.sstatic.net/T5iKc.jpg HTML: <label class="item item ...

Angular 2 Error: Unresolved Promise rejection - Unable to assign value to reference or variable

I'm currently working on an Ionic 2 app that includes a barcode reader feature. However, I encountered the following issue while trying to display data: Unhandled Promise rejection: Cannot assign to a reference or variable! ; Zone: ; Task: Promi ...