3

I get SyntaxError: Parse error at my directive line where I want to use a "&" one-way binding from a parent directive's method

myApp.directive('datasourceDeleteBtn', [function() {
return {
    restrict: 'E',
    replace: true,
    template: '<a href="#">&#x2715</a>',
    scope: {
        datasourceIndex: '@',
        removeParentDiv: '&'
    },
    link: link
};

function link(scope, element, attr) {

    element.bind('click', function(event) {
        event.preventDefault();
        scope.deleteDatasource(scope.datasourceIndex);
    });

    // Notify parent directive
    scope.deleteDatasource = function(datasource_index) {
        // conditional stuff that happens not included
        // {} required for passing values to "&" parent scope method
        scope.removeParentDiv({datasource_index});
    };
}
}]);

HTML

 <parent-div ng-repeat> // this is just a mockup not literal
 <datasource-delete-btn datasource-index="{{$index}}" remove-parent-div="removeParentDiv()"></datasource-delete-btn>
 </parent-div>

The parent div of the ng-repeat that passes removeParentDiv

    // parentDiv directive has this
    scope.datasources = [];
    scope.removeDatasourcePicker = function(index) {
        scope.datasources.splice(index, 1);  // ie take it out
    };

It seems the problem is that Jasmine does not like the { }. Removing the brackets results in the test going through (with typical errors since & requires {}).

ericjam
  • 1,501
  • 2
  • 20
  • 30

1 Answers1

3

You are getting error because you are passing json in wrong format in method

You have not called method passed in directive scope removeParentDiv: '&' correctly from directive. As you are only doing scope.removeParentDiv({datasource_index}); which would not pass index parameter to the method.

For make it working, you need to do couple of changes.

  1. Directive element method should be

    remove-parent-div="removeParentDiv(index)"
    
  2. and while calling it from directive, by having json structure, where index is nothing but parameter and datasource_index is value of it.

    scope.removeParentDiv({index: datasource_index});
    
  3. Do run digest cycle after calling scope.deleteDatasource(scope.datasourceIndex); method from click event so that it will update scope binding.

    element.bind('click', function(event) {
        event.preventDefault();
        scope.deleteDatasource(scope.datasourceIndex);
        scope.$apply(); //to run digest cycle, to keep binding in sync
    });
    
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • Thanks! I'm curious why does an object {index:} need to be passed in a "&" one-way binding. When I use "=" two-way, it works fine without this object syntax. Also looks like my parentDiv function needs more code to be able to understand when it gets an {} versus a normal index string. – ericjam Feb 17 '16 at 21:01
  • @liquified while passing method parameter of `&` method, you need to follow json structure..And yes, when you had `@`(one way binding) we are passing value to directive from its attribute, and when you change it from outer context of directive, that value will update in directive, but updating that value from directive would not intimate(update value in parent) that value has been changed. That's why it known as one way binding. This is reason behind your code not working with `@`, But when you use `=` two way binding it updates value on both side, so thats why it was working for that instance – Pankaj Parkar Feb 17 '16 at 21:08