1

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?

3
  • The directives will set / pass data to templates which they refer. They can not pass data to the html files in which they are included. You shared the directive named member but where you are including it. ?? Commented Dec 29, 2015 at 6:07
  • @SameerK. I have updated the code now. So, if I have to set data and send back to html, I have to do it in controller? Commented Dec 29, 2015 at 6:25
  • Yes thats best way to do. And if you are having issues in setting data controller, will have to find alternate solution. So is possible to provide link to fiddle or plunker replicating your issue?? Commented Dec 29, 2015 at 6:33

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I am following your 2nd approach. But I got below error. undefined is not an object (evaluating 'scope.articleData.content = articleData[0].getArticleResponse.articleDetail.articleContent'
There is another mistake there. I believe it shlould be scope.articleData[0].... I’m updating my response.
Ah, sorry, and I used the variable name articleData even though you are already using it. I’ve changed my answer to use articleContent.content now.
0

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';

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.