Running Controllers from Other Controllers in AngularJS: A Guide

Switching from a jquery mindset to Angular can be challenging for beginners. After reading various tutorials and guides, I am attempting to enhance my skills by developing a customizable dashboard application.

Here is the HTML I have so far:

    <div class="library">
        <div class="dropdown" ng-controller="LibraryCtrl">
            <div id="lib-{{widget.WidgetID}}" ng-repeat="widget in widgets">
                <div data-toggle="tooltip" title="{{widget.WidgetDesc}}">
                    <h2>
                        {{widget.WidgetName}}</h2>
                    <div class="libraryWidget {{widget.WidgetReportType}}">
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="dashboard" ng-controller="DashboardCtrl">
        <div>
            <article>
                <div id="dash-{{widget.WidgetID}}" class="jarviswidget" ng-repeat="widget in widgets">
                    <header role="heading">
                        <h2>
                            {{widget.WidgetName}}</h2>
                    </header>
                    <div role="content" class="content">
                        <div class="inner-spacer">
                            <div class="table">
                            </div>
                        </div>
                    </div>
                </div>
            </article>
        </div>
    </div>

I am currently working on two views - one for the library of available widgets and another for the widgets selected for the dashboard. The library view works fine, but I'm having issues with the dashboard view.

Below is the JavaScript code:

function LibraryCtrl($scope, $http, sharedModels) {
    $http({
        method: 'POST',
        url: '../Services/GetUserWidgetDetails',
        headers: {
            'Content-type': 'application/json'
        }
    }).success(function (data) {
        sharedModels.setProperty(data);
        $scope.widgets = data;
        console.log(data); // showing expected data
    });
}

function DashboardCtrl($scope, sharedModels) {
    var libraryWidgets = sharedModels.getProperty();
    $scope.widgets = libraryWidgets;
    console.log(libraryWidgets); // displaying empty object initially
}

angular.module('dashboard', [])
    .service('sharedModels', function () {
        var libraryModel = {};

        return {
            getProperty: function () {
                return libraryModel;
            },
            setProperty: function (data) {
                libraryModel = data;
            }
        };
    });

Both controllers are supposed to utilize the same model. However, the issue lies in DashboardCtrl rendering its view before LibraryCtrl's success function is completed. What would be the best way in Angular to resolve this problem?

Additionally, if the div.content element in my div.dashboard view needs to display one of multiple sub-templates based on the JSON received from LibraryCtrl, how should I approach this? Unlike jquery templating where I could use IDs for each template, I'm unsure about selecting a template and rendering it within another template in Angular. Any pointers on how to achieve this would be appreciated!

Answer №1

In response to your initial inquiry: Instead of loading data in LibraryCtrl and utilizing it in DashboardCtrl, it is advisable to create a service. The model should be loaded through the service, allowing both controllers to use it.

http://docs.angularjs.org/api/ngResource.$resource

If you haven't explored angular-seed yet, I recommend taking a look at it. It provides a solid foundation for this type of scenario.

Concerning your second query: Directives are highly recommended in this situation. (The solution to many Angular questions often involves creating a directive, especially when dealing with reusable widgets). Consider developing a directive for the entire dashboard as well as one for 'dashboard-item'. Instead of specifying the template directly in the directive declaration, utilize templateUrl...which can incorporate the result of an expression. This allows you to point to different template files based on the type.

Alternatively, you could create a single template file and employ ng-switch to determine which section to display based on the type.

To learn more about creating directives, refer to the tutorial and also check out here.

Skip ahead to "Writing directives (long version)". Save the compilation and linking details for later reference; revisit them only if necessary. The organization of information on that page can be a bit confusing.

Answer №2

Reorganize the data loading process within the service and utilize it in both controllers:

http://jsfiddle.net/ADukg/2631/

var myApp = angular.module('myApp',[]);

function LibraryCtrl($scope, sharedModels) {
    $scope.widgets = sharedModels;
}

function DashboardCtrl($scope, sharedModels) {
    $scope.widgets = sharedModels;
    sharedModels.then(function (x) {
        console.log(x); 
    });
}

myApp.factory('sharedModels', function($q,$timeout) {
    /*
    return $http({
        method: 'POST',
        url: '../Services/GetUserWidgetDetails',
        headers: {
            'Content-type': 'application/json'
        }
    })*/
    // Simulate http request.
    var data = $q.defer();    
    $timeout(function() {
        data.resolve([{WidgetName:'Sproket'}, {WidgetName:'Dohickey'}])
    }, 2000);
    return data.promise;
});

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

`Unable to process JSON information from Google Places`

I am currently working on retrieving a rating for a specific place from Google using a JSON request by placeID. The fields I am requesting are the name and rating of the place. Upon viewing the JSON URL in my browser, I can see the data displayed as follow ...

assigning a numerical value to a variable

Is there a way to create a function for a text box that only allows users to input numbers? I want an alert message to pop up if someone enters anything other than a number. The alert should say "must add a number" or something similar. And the catch is, w ...

Retrieve the script's location from the server prior to the initialization of Angular

Is there a way to dynamically add a script in the index.html page based on the application version? I have a controller that retrieves the app version and attempted to achieve this using AngularJS: var resourceLoader = angular.module('MyTabs&apo ...

React Chart.js allows for consistent spacing for x-axes by displaying dates in a well-organized

After incorporating displayFormats in scales.x, I noticed that my xAxes labels are spaced differently based on the data object they contain. How can I adjust my xAxes labels to have equal spacing? The code snippet is displayed in the following image. Pleas ...

Automatically populate a dropdown menu with options based on the user's birth date

I successfully managed to populate the drop-down fields for months, days, and years. Furthermore, I was able to calculate the age of the user; however, I have restricted it to a maximum of 13 years. Check out the code snippet below: $('#reg-yr' ...

Using VueJS to showcase user input in a dynamic list and a pop-up modal

I am attempting to achieve the following: Use a v-for loop to display form input (name, position, company) as an unordered list, showing only the name input and a button for each person When a button is clicked, a modal will appear displaying all the data ...

What is the CSS method for altering the color of a slider's runnable track upon selection?

Seeking assistance in changing the slider track color upon selection. Struggling to achieve the desired outcome of altering the color as it slides. CSS: /* Custom Styles */ .text-size-slider { line-height: 100%; font-size: 14px; position: relative ...

What is the best way to utilize a JavaScript variable as a background within an inline style sheet?

I have a fun project for this evening - I am trying to make my website load a different background image every time the page is refreshed. Earlier on in this project, I managed to make the background interact with window size and screen resolution similar ...

Alignment of Material-UI dialogue buttons on the left side

I have a Dialog containing three buttons as shown below: https://i.stack.imgur.com/T6o35.png Here is the JSX code: <DialogActions classes={{ root: this.props.classes.dialogActionsRoot }} > <Button classes={{ root: this.props ...

How to Utilize Knockout's BindingHandler to Integrate JQuery.Datatables Select Feature?

I've developed a custom KO bindingHandler (view it here) to assist in updating the DataTable. The documentation for JQuery.DataTable.Select regarding how to access data requires a handle. You can see the details here. var table = $('#myTable&a ...

Dealing with Jquery ajax errors in Internet Explorer

Trying to implement an ajax call: var sourceUrl = ' http://api.official.fm/tracks/D4lw?fields=streaming,cover&api_version=2'; jQuery.ajax({ url: sourceUrl, dataType: 'jsonp', }).done(function( response ) { }).fail(funct ...

Enhancing Angular's templates and handling cache invalidation

I have encountered a dilemma in my Angular1 project where changes made to an html template are not immediately visible to users without performing a hard refresh. Ideally, I would like to implement a cache service that checks for a timestamp and invalidate ...

Using the quote and saying "quotation marks"

Any ideas on how to approach this? This is driving me crazy: $toReturn .= " function addProd(pExists) { document.getElementById('products').innerHTML = \"<tr><td id='prod_n'><input type='text&apos ...

Is there a way for me to reset the quantity and price fields when I don't choose any product from the drop-down menu?

Whenever I choose a product from the drop-down menu, the price and quantity values are fetched from the database. However, when I select the option SELECT MOTHERBOARD, which has no value, the quantity field displays the value 1 and the Total Price field sh ...

Having trouble selecting an option from the database in Angular JS?

In my Angular.js application, I am using a select option list that is populated from an sql server database. The list populates correctly, but I am having trouble displaying data back from the sql server. To populate the list from the database: <selec ...

In what way can I obtain CSS comments utilizing jQuery?

I am trying to figure out how I can access CSS comments that are included in an external stylesheet. In order to demonstrate, I have loaded a sample CSS using the following code: <link rel="stylesheet" type="text/css" media="all" href="test.css" /> ...

`Scrolling through a horizontal menu with no scrollbar present`

Is there a way to create a horizontal menu that can scroll left or right without the scrollbar? I'm looking for a solution like adding on-screen arrow buttons or implementing mouseover functionality. What would be the best approach? div.scrollmenu ...

Implementing Node.JS ajax to update current JSON information

I am seeking assistance in updating data within a JSON file using NODE.JS. Currently, my method adds the data with the same ID as expected. However, upon receiving the data back, it eliminates the last duplicate because it encounters the old value first. I ...

The function socket.on(..) is not being triggered

Currently, I am in the process of developing a straightforward website to showcase socket communication and chat capabilities. The server side is coded using Python Flask app, while the client-side utilizes JavaScript. Below is an excerpt from the server c ...

Exploring ways to create simulated content overflow using react-testing-library

I have integrated material-table with material ui to develop a spreadsheet application. One of the features I have added is setting a maximum width of 50px for cells. If the content in a cell exceeds this width, it will display an ellipsis at the end of ...