Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a TimelineController that has a publish function on the scope, that will send some data to the server.

My timeline is composed by 2 directives

  • timeline (Element)
  • share-post (Element)

I would like to be able to call from the share-post directive the publish function on my TimelineController is that possible?.

Controller

function TimelineController($scope,TimelineService)
    {
        $scope.posts = [];

        $scope.publish = function(wall_type,wall_id,text,video,image) {
            console.log('click controller');
            TimelineService.publishPost(wall_type,wall_id,text,video,image).$promise.then(function(result){
               $scope.posts.push(result.response);
            });
        };
    }

Timeline Directive:

function timelineDirective() {

        return {
            restrict: 'E',
            replace: true,
            scope: {
                type: '@',
                ids: '@',
                postime: '&',
                posts: '='
            },
            templateUrl:"/js/templates/timeline/post-tmpl.html",
            controller: function($scope,$element) {

                this.type = $element.attr('type');
                this.ids = $element.attr('ids');
            }
        }
    };

Timeline Directive Template

<ol class="timeline" ng-init="postime({wall_type:type,wall_id:ids})">
    <li>
       <share-post></share-post>
    </li>
    <li ng-repeat="post in posts">
       {{post.text}}
    </li>
</ol>

SharePost Directive: From this directive I would like call the publish on the TimelineController

function sharePost() {

        return {
            restrict: 'E',
            replace: true,
            require: "^timeline",
            templateUrl:"/js/templates/timeline/share-tmpl.html",
            link: function($scope,$element,$attr,ctrl) {
                $scope.pub = function() {

                    // This does not work because it call the parent directive
                    // Instead of controller
                    $scope.publish(ctrl.type, ctrl.ids, $scope.text);
                }
            }
        }
    };

Sharepost Directive Template

<div class="module comment">
    <div class="content">
        <textarea class="form-control" ng-model="text" placeholder="What is going on..." rows="2"></textarea>
    </div>

    <button type="button" class="btn" ng-click="pub()"> Share</button>

</div>
share|improve this question
    
I think you should either inject the TimelineService service directly into your directive or inject the "publish" function into the scope of your directive using attributes –  Neozaru Oct 29 '14 at 14:41
    
I would like avoid to inject the Service to the directive –  Fabrizio Oct 29 '14 at 14:54
    
@Fabrizio, let me get this straight, do you want to fire a click event on the controller from a directive? –  jack.the.ripper Oct 29 '14 at 14:59
    
@jack.the.ripper I want fire the function $scope.publish in the controller from an event click from the directive. –  Fabrizio Oct 29 '14 at 15:04

2 Answers 2

well you use your directive just to bind the event click from the controller, something like:

angular.module('module').directive('sharePost', [
        function(){
            return {
                link: function (scope, element, attr) {
                    var clickAction = attr.clickAction;
                    element.bind('click',function (event) {
                        scope.$eval(clickAction);
                    });
                }
            };
    }]);

html

 <a sharePost click-action="publish(wall_type,wall_id,text,video,image)"> publish</a>
share|improve this answer
    
Thanks for your answer, it seem interesting but I didn't get where that function come from, that function was meaning the publish function on the controller? Thanks –  Fabrizio Oct 29 '14 at 15:56
    
sorry I just copied and pasted it from your code, forgot to reference the controller scope, that's just your publish function –  jack.the.ripper Oct 29 '14 at 16:00
1  
Ok, now make more sense, I'll try that it sounds good to me :) –  Fabrizio Oct 29 '14 at 16:03
    
np, maybe that may lead you on your final goal, good luck! –  jack.the.ripper Oct 29 '14 at 16:07
    
I tried this but it doesn't work because the directive still doesn't know about the publish function. That sharePost directive is a child directive of another directive –  Fabrizio Oct 29 '14 at 17:05

Change your directive to have an extra item in the scope like this onPublish: "@" then in your html you can pass a pointer to the controller function you want to invoke like this:

 <share-post on-publish="publish"></share-post>

to call this from the directive you have to do:

$scope.onPublish()(ctrl.type, ctrl.ids, $scope.text)
share|improve this answer
    
This way does not work, because how you can see the share-post directive is child of timeline if I pass the publish method how you showed it try to get the parent directive publish I guess. –  Fabrizio Oct 29 '14 at 14:53
    
I missed the nested directives, you can achieve calling the controller method by passing the function from the controller to the parent directive, and then from there to the child one. But this is a bit nasty. Another way would be to have a service injected (a new one) in the child directive and in the controller, so you can use that to communicate –  Sebastian Piu Oct 29 '14 at 15:08
    
Yhea you explained what i was saying better then me, it is nasty to pass from parent directive to child directive. Thanks a lots, may you show a small example on how with a service I can put in communication, directive and controller? –  Fabrizio Oct 29 '14 at 15:11
    
Now that I think, it would not be wrong to declare which method you want called once a click in the directive happens, as long as the attribute is named accordingly, e.g. on-post-clicked or something of that sorts –  Sebastian Piu Oct 29 '14 at 15:18
    
That's ok but I don't think this way is the more correct way: pastebin.com/Ytjbjq9x because I pass the publish scope on the timeline directive that it doesn't need of it but is just a bridge to let that scope available to the child directive. Correct me if I'm wrong, and if this solution is fine –  Fabrizio Oct 29 '14 at 15:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.