Search code examples
jqueryangularjsangularjs-scopeangular-directive

Controller to Directive and Directive to controller correct way of communcation


I have a page, which contains the pageNavigator with page display content. according to the user click on the appropriate buttons(links) I am updating the page.

I made the directive for :page navigator as 'docNavigation' and included with my home html.

Now i requre,

When page loads,

  1. my doc page should show the count as what i mensioned in homeController and the switch case last should be set as 20 which i set in homeController.

  2. when user interacts i would like to update the count in homeController to update the page content.

What would be the correct way to get this?

here is my directive:

"use strict";

angular.module("docNaviDir", [])
    .directive("docNavigation", function () {
        return {
            restrict : "E",
            replace : true,
            templateUrl : '/views/directiveViews/docNavigation.html',
            link : function (scope, element, attr, controller) {
               var count = 0;
                element.find('a').on('click', function () {

                    var Id = $(this).prop('id');
                    switch(Id) {
                        case 'first':
                            count = 1; //update to `homeController`
                            break;
                        case 'prev':
                            count -= 1;  //update to `homeController`
                            break;
                        case 'next':
                            count += 1;  //update to `homeController`
                            break;
                        case 'last':
                            count = scope.totalPages; //get from `homeController`
                            break;
                    }
                scope.$apply(function () {
                    count = count;
                })
                })
            }
        }
    })

my homeController:

"user strict";

angular.module("ngTenderDocument")
    .controller('homeController', function ($scope) {
        $scope.count = 0; //pass to directive and update by user
        $scope.totalPages = 20; //pass to directive
    })

my View:

<doc-navigation></doc-navigation> //directive
<h1>This is from home! Now you start to count, count is : {{count}}</h1> //count need to show the appropriate updates here.

my Navi View :

<nav class="navbar navbar-inverse">
    <ul class="nav navbar-nav">
        <li class="active"><a id="first" href="#">First</a></li>
        <li><a id="prev" href="#">Previous</a></li>
        <li><a id="next" href="#">Next</a></li>
        <li><a id="last" href="#">Last</a></li>
    </ul>
</nav>

Solution

  • I'll use an object definition and scope mapping like

    $scope.page = {
        totalPages: 10,
        count: 4
    };
    

    then

    app.directive("docNavigation", function () {
        return {
            restrict: "E",
            replace: true,
            //use your url
            template: '<div>' + '<a data-type="first" href="">first</a>' + '<a data-type="prev" href="">prev</a>' + '<a data-type="next" href="">next</a>' + '<a data-type="last" href="">last</a>' + '</div>',
            scope: {
                page: '='
            },
            link: function (scope, element, attr, controller) {
                element.find('a').on('click', function () {
                    //using hard coded ids in a directive is dangerous as there can be other elements with the same id
                    var type = angular.element(this).attr('data-type');
                    switch (type) {
                        case 'first':
                            scope.page.count = 1; //update to `homeController`
                            break;
                        case 'prev':
                            scope.page.count -= 1; //update to `homeController`
                            break;
                        case 'next':
                            scope.page.count += 1; //update to `homeController`
                            break;
                        case 'last':
                            scope.page.count = scope.page.totalPages; //get from `homeController`
                            break;
                    }
                    scope.$apply(function () {})
                })
            }
        }
    });
    

    Demo: Fiddle