Nate May
Nate May

Reputation: 4062

How to use directive-defined events to update my model

I am creating drag and drop functionality by creating a <dragItem> directive and a <droptTraget> directive, but I don't understand yet how to work with the inner and out scope in this way.

Here are my directives. The events triggers the functions properly, I just want the on dragstart event to store a value of the drag element and the drop event to trigger the function testAddSet() which adds the drag value to my model.

drag

angular.module('app.directives.dragItem', [])
  .directive('dragItem', function(){
    return { // this object is the directive
      restrict: 'E',
      scope: {
        excercise: '='
      },
      templateUrl: "templates/dragTile.html",
      link: function(scope, element, attrs){
        element.on('dragstart', function (event) {
        var dataVar = element.innerText; 
          // It's here that I want to send a dataVar to the $scope
        });
      }
    };
  });

drop

angular.module('app.directives.dropTarget', [])
  .directive('dropTarget', function(){
    return { // this object is the directive
      restrict: 'E',
      scope: {
        day: '='
      },
      templateUrl: "templates/calDay.html",
      link: function(scope, element, attrs){
        element.on('drop', function (event) {
            event.preventDefault();
            // It's here that I'd like to take the value from the drag item and update my model
           testAddSet() // doesn't work
           $parent.testAddSet() // doesn't work
        });
        element.on('dragover', function (event) {
          event.preventDefault();
        });
      }
    };
  });

Upvotes: 0

Views: 284

Answers (2)

georgeawg
georgeawg

Reputation: 48968

Since you are using isolate scope, you need to define an attribute for the function binding.

angular.module('app.directives.dropTarget', [])
  .directive('dropTarget', function(){
    return { // this object is the directive
      restrict: 'E',
      scope: {
        day: '=',
        //Add binding here
        testAddSet: '&'
      },
      templateUrl: "templates/calDay.html",
      link: function(scope, element, attrs){
        element.on('drop', function (event) {
            event.preventDefault();
            //Invoke the function here
            scope.testAddSet({arg: value, $event: event});
        });
        element.on('dragover', function (event) {
          event.preventDefault();
        });
      }
    };
  });

In your template, connect the function using the directive attribute.

<drop-target test-add-set="fn(arg, $event)" day="x"></drop-target>

For more information on isolate scope binding, see AngularJS $compile Service API Reference - scope.


I recommend that the event object be exposed as $event since that is customary with AngularJS event directives.

$event

Directives like ngClick and ngFocus expose a $event object within the scope of that expression. The object is an instance of a jQuery Event Object when jQuery is present or a similar jqLite object.

-- AngularJS Developer Guide -- $event

Upvotes: 1

C.C.
C.C.

Reputation: 575

I think the easiest way to get your cross-directive communication is to make a scope variable on the host page and then pass it double-bound ('=') to both directives. That way, they both have access to it as it changes.

Upvotes: 0

Related Questions