Sanjay
Sanjay

Reputation: 443

Unable to pass data from directive to html in angularjs

In angular js, I have constructed a tree for navigation. On click of the left nav links, I want to load data (it is static data, I have to read it form a json file and display) in the page. However, I am not able to make the function call on click of the leftnav.

HTML Code:

<div class="collapse-toggler"><collection collection='tasks'></collection</div>

<div id="articleContent">{{articleContent}}</div> 

JS File:

app.directive('collection', function() {
    return {
        restrict: "E",
        replace: true,
        scope: {
            collection: '=',
            articleData: '=',
            articleContent: '='
        },
        template: "<ul><member ng-repeat='member in collection' member='member' article-data='articleData' article-content='articleContent'></member></ul>"
    }
});
app.directive('member', function($compile) {
    return {
        restrict: "A",
        replace: true,
        scope: {
            member: '=',
            articleData: '=',
            articleContent: '='
        },
        template: "<div><li><a ng-href='#' ng-click='getArticleContent()'>{{member.title}}</a></li></div>",
        link: function(scope, element, attrs) {
            scope.getArticleContent = function() {
                scope.articleContent = articleData[0].getArticleResponse.articleDetail.articleContent;
            }

            if (angular.isArray(scope.member.tocItem)) {
                if (scope.member.hasChildren == "true") {
                    for (var i = 0; i < scope.member.tocItem.length; i++) {
                        if (scope.member.tocItem.title) {
                            scope.member.tocItem.title.hide = true;
                        }
                    }
                }
                element.append("<collection collection='member.tocItem'></collection>");
                $compile(element.contents())(scope)
            }
        }
    }
});

app.controller('apdController', function($scope, getTocService) {
    var sampdata = getTocService.getToc('bookid-1');
    $scope.tasks =sampdata;

    $scope.getArticleContent = function(){
        alert('hello');
        $scope.articleContent = articleData[0].getArticleResponse.articleDetail.articleContent;
    };
});

I was able to set articleContent data in link function but not able to pass back to html. When I tried to set that in controller, I am not able to make function call.

There is no error in browser console. I am not getting my mistake. Can someone please point it out?

Upvotes: 1

Views: 918

Answers (2)

Black Mamba
Black Mamba

Reputation: 15545

I've spent a lot of time in understanding how to change the controller object from within a directive after all I was able to find a solution which is to use $parent

consider a variable in your controller :

$scope.sampleVariable = 'hello' ;

and inside the directive you need to do like this inside your link:

scope.$parent.sampleVariable = 'Hello from directive';

Upvotes: 0

cdauth
cdauth

Reputation: 7558

I think there are three problems here.

One is in this line:

scope.articleContent = articleData[0].getArticleResponse.articleDetail.articleContent;

You are trying to override the articleContent of the parent scope, but like this you are just setting a new value on the child scope. See for example this article about scope inheritance.

The solution is to make articleContent a property of another object which you don’t need to overwrite. In you controller, set:

$scope.articleContent = {};

Modify your HTML like this:

<div id="articleContent">{{articleContent.content}}</div> 

And finally the setter function in the directive:

scope.getArticleContent = function() {
    scope.articleContent.content = articleData[0].getArticleResponse.articleDetail.articleContent;
}

The second problem (and I’m not sure why this hasn’t produced an error in the browser console before) is that you are referring to articleData where it should be scope.articleData. So the code in your directive should actually be:

scope.getArticleContent = function() {
    scope.articleContent.content = scope.articleData[0].getArticleResponse.articleDetail.articleContent;
}

The third problem is that you are actually not passing an articleData object to your directive, so an error will be thrown becuase scope.articleData[0] cannot be accessed.

Upvotes: 1

Related Questions