1

The setup: I have a page (angular) with a repeater in it.

<tr ng-repeat="row in results.leads">
    <td>{{row.SubmittedByName}}</td>

Within the repeater, there is a column with a button that opens a modal to alter that row's data. The modal, in turn, has a button for the saving of the record, that closes the current modal, opens a new modal, let's the user enter a comment, saves, and then closes the modal.

This all works great. Fantastic.

What DOESN'T work is... when the modal closes, the ng-repeat is supposed to refresh, as the actions taken in the modal will actually remove rows from the data. If I refresh the page manually, the row vanishes - but without refreshing the page, nothing happens.

The Angular Controller: 'use strict';

angular.module('leadApproval.controllers', []).

    //This is the main page core method - The data is loaded here, and the in-table-row buttons work from here.
    controller('LeadApprovalCtrl', function ($scope, $location, $modal, api, notificationService) {
        $scope.currentPage = 1;
        $scope.pageSize = 13;
        $scope.loaded = false;
        $scope.totalItems = 0;
        $scope.head = {};
        $scope.sort = {};
        $scope.selectedCls = null;
        $scope.changeSorting = null;
        $scope.setPage = null;
        $scope.results = null;

        $scope.loadQueue = (function () {
            api.queue.load(function (data) {
                if (data.error) {
                    notificationService.error('<h4>An error occurred..</h4>' + data.error);
                } else {
                    $scope.results = data;
                    $scope.loaded = true;
                }
            });
        });

        $scope.acceptLead = function (leadId) {

            var modal = $modal.open({
                templateUrl: '/Content/LeadApproval/Approved.html',
                controller: 'ApprovedCtrl',
                windowClass: '',
                resolve: { leadId: function () { return leadId; } }
            });

            modal.result.then(function (result) {
                if (result === 'save') {
                    $scope.loadQueue();
                    notificationService.success('Lead successfully approved.');
                }
            });
        }

        $scope.searchLead = function (id) {
            $location.path('search/' + id);
        }

        $scope.rejectLead = function (leadId) {
            var modal = $modal.open({
                templateUrl: '/Content/LeadApproval/NotApproved.html',
                controller: 'NotApprovedCtrl',
                windowClass: '',
                resolve: { leadId: function () { return leadId; } }
            });

            modal.result.then(function (result) {
                if (result === 'save') {
                    $scope.loadQueue();
                    notificationService.success('Lead successfully removed from queue.');
                }
            });
        };

        $scope.editLead = function (id) {
            window.location = "/Customers/Edit/" + id;
        }

        // Open Lead Detail
        var leadHistoryOverviewScope = {
            item: {}
        };

        $scope.showLeadDetail = function (customerId, leadId) {
            leadHistoryOverviewScope.item = { customerId: customerId, leadOppId: leadId };
            var modal = $modal.open({
                templateUrl: '/content/leadApproval/leaddetail.html',
                controller: 'LeadHistoryCtrl',
                windowClass: 'wide-modal-window',
                resolve: { childScope: function () { return leadHistoryOverviewScope; } }
            });
        };

        $scope.loadQueue();
    }).


// Lead History controller
    controller('LeadHistoryCtrl', function ($scope, $modal, $modalInstance, api, notificationService, childScope) {
        $rootScope.loaded = false;
        $scope.customerLoaded = false;
        var historyStartDate = new moment().subtract(6, 'months').format("YYYY-MM-DD");
        var historyEndDate = new moment().format("YYYY-MM-DD");
        $scope.orders = [];
        $scope.history = [];

        $scope.showActionButtons = true;

        api.queue.queryOrders(childScope.item.customerId, historyStartDate, historyEndDate, function (result) {
            $scope.orders = result || [];
            $scope.ordersLoaded = true;
        });

        api.queue.details.get({ id: childScope.item.customerId, leadOppId: childScope.item.leadOppId }, function (result) {
            $scope.history = result;
            $scope.customerLoaded = true;
        });

        $scope.acceptLead = function (leadId) {
            $modalInstance.close();

            var modal = $modal.open({
                templateUrl: '/Content/LeadApproval/Approved.html',
                controller: 'ApprovedCtrl',
                windowClass: '',
                resolve: { leadId: function () { return leadId; } }
            });

            modal.result.then(function (result) {
                if (result === 'save') {
                    $scope.loadQueue();
                    notificationService.success('Lead successfully approved.');
                }
            });
        }

        $scope.rejectLead = function (leadId) {
            $modalInstance.close();

            var modal = $modal.open({
                templateUrl: '/Content/LeadApproval/NotApproved.html',
                controller: 'NotApprovedCtrl',
                windowClass: '',
                resolve: { leadId: function () { return leadId; } }
            });

            modal.result.then(function (result) {
                if (result === 'save') {
                    $scope.loadQueue();
                    notificationService.success('Lead successfully removed from queue.');
                }
            });
        };

        $scope.editLead = function (id) {
            $modalInstance.close();
            window.location = "/Customers/Edit/" + id;
        }

        $scope.cancel = function () {
            $modalInstance.dismiss('cancel');
        };
    })
;

The thing I've noticed is that $scope.loadQueue(); (as seen about 17 lines up) throws an error as an undefined object. For some reason "LeadHistoryCtrl" can't see the scope in "LeadApprovalCtrl", and thus can't refresh the ng-repeat. I've even tried just copying the loadQueue function into LeadHistoryCtrl, but to no real effect - the code then functions... but the main page doesn't refresh.

So, the question: how do I get the loadQueue() call in LoadHistoryCtrl to call the method in LeadApprovalCtrl, and refresh the main page ng-repeat table?

PKD
  • 685
  • 1
  • 13
  • 37
  • After closing modal you don't modify model that's used for `ng-repeat` so it's not changing – maurycy Apr 22 '15 at 16:16
  • That's what `$scope.loadQueue();` is supposed to be doing - calling back to LeadApprovalCtrl's instance of the loadQueue function, to update the model. – PKD Apr 22 '15 at 16:18
  • What does your HTML look like, are the controllers nested within each other, or is there a parent controller? Creating a service would be the best way for cross controller communication, but if you're really adverse to that, nesting controllers can allow for some communication. [This video](https://egghead.io/lessons/angularjs-the-dot) goes into some more detail. – blindworld Apr 22 '15 at 16:46

1 Answers1

0

Typically you would want to move that function to a service if you need to access it from multiple controllers. In Angular you cant communicate directly to another controller from a controller. You can use $scope.broadcast / $scope.emit to trigger this. What's the correct way to communicate between controllers in AngularJS?

Community
  • 1
  • 1
Mat Wolff
  • 26
  • 3
  • I could accept that, except that I'm actually doing a cross-controller communication on another page (which only adds to my confusion, since it works there and isn't working here). – PKD Apr 22 '15 at 16:51
  • Can you throw that into a fiddle or plnkr? I would like to see the code for the cross communication. – Mat Wolff Apr 22 '15 at 17:16
  • as blindworld said if you nest the controllers you can allow for some communication as seen in this plnkr http://plnkr.co/edit/LH81qIl6wpmjdxVHDOUE?p=preview – Mat Wolff Apr 22 '15 at 17:25