Eka Rudianto
Eka Rudianto

Reputation: 4755

passing defined object to another custom directive angularjs

so I have this custom directives that you could see below.

myApp.directive('myDirective', function (testService) {
    return {
        restrict:'EA',
        link:function (scope, element, attr) {
           //defined the object
           var object = new object();
           testService.setObject(object);
    }
   }
});

myApp.directive('mySecondDirective', function (testService) {
    return {
        restrict:'EA',
        link:function (scope, element, attr) {
           //call the variable from previous custom directive
           console.log(testService.getobject()); -> always return undefined
    }
   }
});

and this is the html structure where I used the directives above.

<my-directive></my-directive>

<my-second-directive></my-second-directive>

there I want to retreive the object that contains new object() from previous custom directive, but it always return an undefined I wonder how could I do this without using require nor isolated scope as well.. could you guys help me ?

UPDATE I create a service to provide the facility to set and retreive the object and apparently it returned undefined because I set the custom direcitve this way

<my-second-directive></my-second-directive>

<my-directive></my-directive>

and this is the service

define(
        ['services/services'],
        function(services)
        {
            'use strict';

            services.factory('testService', [function() {
                    var me = this;
                    var testObject = '';

                    return {
                        setObject: function(object) {
                            me.testObject = object;
                        },
                        getObject: function() {
                            return me.testObject;
                        }
                    }
                }
            ]);
        }
);

the thing is that I actually set the html markup like I already mentioned above which is

<my-second-directive></my-second-directive>

<my-directive></my-directive>

so could you give me some advice on how should I do this ?

note* that the passing object actually worked I prefer using services because it will easy to mantain latter. The question is how do I make the object accessible from another directive even though the initiate install of the object (set the object) in the directive that I defined at the html markup, as the last position of the html it self ?

UPDATE this is the PLUNKER that I've been made for you to understand the question it self

Upvotes: 1

Views: 727

Answers (3)

Srinivas Paila
Srinivas Paila

Reputation: 827

Expanding from what @gmartellino said.

Anything that you wanted to do after listening to the event in second directive, can have a callBack method and use it.

app.directive('mySecondDirective', function(testService) {
  return {
    restrict: 'EA',
    link: function(scope, elm, attr) {
      // what if I created like this ? 
      // define the test variable
      var test;

      scope.$on('objectSet', function(){
        //set the variable
        test = testService.getObject();
        console.log('retrieving object : ', testService.getObject());

        //Anything that you wanted to do 
        //after listening to the event 
        //Write a callBack method and call it
        codeToExecuteAsCallBack();
      })

      //then use this method to make a call back from the event 
      //and outside the event too.
      var codeToExecuteAsCallBack = function(){
        console.log(test);
      }
      codeToExecuteAsCallBack();
    }
  }
});

Updated plnkr link

Upvotes: 0

gmartellino
gmartellino

Reputation: 707

You could achieve this by firing a custom event and then listening for it in the second directive. Here's an updated plunker: http://plnkr.co/edit/512gi6mfepyc04JKfiep?p=info

Broadcast the event from the first directive:

app.directive('myDirective', function(testService) {
  return {
    restrict: 'EA',
    link: function(scope, elm, attr) {
      var object = {};
      testService.setObject(object);
      console.log('setting object');
      scope.$broadcast('objectSet');
    }
  }
});

... and then listen for it on the second:

app.directive('mySecondDirective', function(testService) {
  return {
    restrict: 'EA',
    link: function(scope, elm, attr) {
      scope.$on('objectSet', function(){
        console.log('retrieving object', testService.getObject());
      })
    }
  }
});

You could also pass data along with the event, if you wanted to emit a specific piece of data to be picked up by the second directive.

Upvotes: 1

dfsq
dfsq

Reputation: 193271

1). Scope. Since you don't want to use controllers and isolated scope, then you can simply set this object as scope property.

myApp.directive('myDirective', function() {
    return {
        restrict: 'EA',
        link: function(scope, element, attr) {

            var object = {};
            object.test = 21;

            // set object as scope property
            scope.object = object;
        }
    }
});

myApp.directive('mySecondDirective', function() {
    return {
        priority: 1,  // priority is important here
        restrict: 'EA',
        link: function(scope, element, attr) {
            console.log('Retrieve: ', scope.object);
        }
    }
});

Just make sure you are also defining priority on the second directive (only if both directive a applied to the same element) to make sure it's evaluated in proper turn (should be bigger then the one of myDirective, if omitted it's 0).

2). Service. Another simple solution is to use service. You can inject custom service into both directives and use it storage for you shared object.

Upvotes: 0

Related Questions