Aj1
Aj1

Reputation: 973

Watch Directive Scope Variable From Controller

Below is my directive, which is an utility (reusable).

 var ChartNavigationDirective = { 'ChartNavigation': function (Items) {
return {
    restrict: 'EA',
    require: '?ngModel',
    replace: false,
    template: '<div class="chart-nav">' +
             ' </div>',
    scope: {
        options: '=ChartNavigation'
    },
    link: function (scope, element, attrs) {

        scope.parameters = {
            "prev_arrow": "#prev-arrow",
            "next_arrow": "#next-arrow"
        };

        Items.getItems(scope.options.Source, scope.options.Type).then(function (d) {

            scope.links = d.Items;
            for (var link in scope.links) {
                scope.links[link].Id = link;
            }
            var chartList = scope.links;
            setNavigation(chartList);
        });
        var setNavigation = function (chartList) {

            scope.totalCharts = chartList.length;
            if (scope.totalCharts <= 0) {
                $(scope.parameters.next_arrow).removeClass("on").addClass("off");
                $(scope.parameters.prev_arrow).removeClass("on").addClass("off");
            }
            if (scope.totalCharts > 0) {
                scope.currentItem = scope.links[0];                   
                scope.currentIndex = Number(scope.currentItem.Id) + 1;
                $(scope.parameters.prev_arrow).removeClass("off").addClass("on");
                $(scope.parameters.next_arrow).removeClass("off").addClass("on");
            }
            updateNavigation();
        };

        var updateNavigation = function () {

            if (scope.currentIndex <= 1) {
                $(scope.parameters.prev_arrow).removeClass("on").addClass("off");
            }
            else {
                $(scope.parameters.prev_arrow).removeClass("off").addClass("on");
            }
            if (scope.currentIndex >= scope.totalCharts) {
                $(scope.parameters.next_arrow).removeClass("on").addClass("off");
            }
            else {
                $(scope.parameters.next_arrow).removeClass("off").addClass("on");
            }
        };
        scope.Previous = function () {

            var currentIdx = scope.currentIndex;
            var previousIdx = currentIdx - 1;
            if (previousIdx >= 0) {
                scope.currentItem = scope.links[previousIdx - 1];                   
                scope.currentIndex = Number(scope.currentItem.Id) + 1;                   
            }
            updateNavigation();
        };

        scope.Next = function () {

            var currentIdx = scope.currentIndex;
            var nextIdx = currentIdx + 1;
            if (nextIdx <= scope.totalCharts) {
                scope.currentItem = scope.links[nextIdx - 1];
                scope.currentIndex = Number(scope.currentItem.Id) + 1; ;
               }
            updateNavigation();
        };
    }
    };
    }
   };

I would like to watch scope.currentItem from my controller. I did try using broadcast it's working fine. But I would like use watch instead. Here is my controller.

 var myController = function ($scope) {

$scope.templateUrl = '/_layouts/AngularControls/myController/Views/Charts.html';

$scope.currentConfig = '';

//    $rootScope.$on('curentConfig', function (event, args) {
//        $scope.currentConfig = args.data;
//    });

$scope.$watch("currentItem", function () {
    alert(JSON.stringify($scope.currentItem));
 });

 }

Can anyone point out where I am doing mistake ? If there any suggestions Please let me know.

Upvotes: 0

Views: 82

Answers (2)

Aj1
Aj1

Reputation: 973

I figured it my self. Using $rootScope in both directive an controller and watching for the $rootScope variable has resolved the issue.

In Direcive :

$rootScope.currentItem= myItem;

In Controller:

$scope.$watch("currentItem", function () {
    $scope.currentConfig = $rootScope.currentItem;
});

Upvotes: 0

Shomz
Shomz

Reputation: 37711

You're trying to watch a directive scope variable from a controller. That won't work because they are two different scopes (you are using an isolate scope in your directive).

You can watch from the directive controller (but I'm not sure that's what you want), or simply pass in the main controller scope variable into the directive, and have the directive manipulate it instead of its own scope variable. I guess using scope.$parent.currentItem is also possible, but definitely not recommended because of the directive reusability.

Broadcasting is also fine, not sure why you don't want to do it.

This is your structure:

controller scope
-  directive scope
     currentItem

And you're watching for this:

controller scope
   watching for currentItem here, it does not exist
-  directive scope
     currentItem

Upvotes: 1

Related Questions