Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass Arguments from directive to controller function

I've seen lots of these questions but haven't found a solution that works. here is a fiddle that doesn't work but should.

http://jsfiddle.net/cdparmeter/j2K7N/2/

Controller:

$scope.foo = function (textArray) {
    console.log(textArray)
};

Directive:

return {
    restrict: 'E',
    replace: 'true',
    scope: {
        methodToCall: '&method'
    },
    template: "<div>
        <input ng-model='textToPush'/>
        <button ng-click='pushText'>Push</button>
        <button ng-click='finish'>Finish</button>
    </div>",
    link: function (scope, element, attrs) {
        scope.paragraphs = [];
        scope.pushText = function () {
            scope.paragraphs.push(scope.pushText);
            scope.pushText = "";
        }
        scope.finish = function () {
            scope.methodToCall(scope.paragraphs)
        }
    }
}

HTML:

<div ng-app="MyApp">
    <div ng-controller="MyController">
        <container data-method="foo">
    </div>
</div>

I'm building an array inside my directive that needs custom handling in the controller of the parent scope. I know I can throw a watch in the parent scope on a model I pass into my directive but that seems hackish and dirty. any suggestions?

like image 919
C-Rad Avatar asked Oct 03 '13 03:10

C-Rad


1 Answers

Before answering your question I must say that your script contains a few errors:

  1. You're binding the input to a variable called textToPush, and then using a different one inside the pushText function (pushText);
  2. You're not setting the ng-click directive correctly; it should be ng-click="pushText()" instead of ng-click="pushText". The same for finish;

Now, back to your question. In order to call a function of the parent scope passing arguments, you can get a reference to that function first, and then execute it:

scope.finish = function () {
  var func = scope.methodToCall();                
  func(scope.paragraphs);
}

Here's a working version of your script.

You could also do this, if you prefer:

scope.finish = function () {
    scope.methodToCall({value: scope.paragraphs});                                
}

But for this code to work you should change your markup to:

<container data-method="foo(value)"/>

Here's another jsFiddle showing the solution above.

like image 76
Michael Benford Avatar answered Nov 07 '22 05:11

Michael Benford