0

I have the following controller, and directive declaration.

<div ng-controller="DocumentController as dc" data-drop-zone url="api/document/upload">

How do I wire the document controller to call a method on the directive.

<button ng-click="dc.start()" />

drop-zone is typescript, defined as follows.

export class DocumentDropZone implements ng.IDirective {
    url: string;

    constructor(public $log, public $compile) {
    }

    public start(): void {
        this.$log.log(`start processing files...`);
    }

    public link: Function = (scope: any, element: angular.IAugmentedJQuery, attrs: angular.IAttributes) => {
        this.$log.log(`initialising drop zone`);
        ... // left out for brevity.

The document controller is simple.

class DocumentController
{
    static $inject = ['$log'];

    constructor(public $log: ng.ILogService) {
    }

    public start(): void {
        // CALL THE DIRECTIVE "start" METHOD SOMEHOW...
        this.$log.log(`start uploading files`);
    }
}

If I attempt to use an isolated scope on the directive I get an error:

Multiple directives [ngController, dropZone (module: panda)] asking for new/isolated scope on:

2
  • "How do I wire the document controller to call a method on the directive." - Elaborate on this please. I sense that you are trying to do something wrong. Short answer: you never call directive methods. Commented Jul 25, 2016 at 14:34
  • the directive owns the dropzone, so a method on the directive needs to be called in order to call a corresponding method on the owned dropzone Commented Jul 25, 2016 at 14:43

1 Answer 1

1

Directives with isolated scopes need to be on a child element from elements with the ng-controller directive.

<div ng-controller="DocumentController as dc" >

  <div my-directive command="dc.myDirCommand">
  </div>

</div>

The ng-controller directive uses inherited scope. A directive with isolated scope needs to be on a different element.

From the Docs:

In general it's possible to apply more than one directive to one element, but there might be limitations depending on the type of scope required by the directives. The following points will help explain these limitations. For simplicity only two directives are taken into account, but it is also applicable for several directives:

  • no scope + no scope => Two directives which don't require their own scope will use their parent's scope
  • child scope + no scope => Both directives will share one single child scope
  • child scope + child scope => Both directives will share one single child scope
  • isolated scope + no scope => The isolated directive will use it's own created isolated scope. The other directive will use its parent's scope
  • isolated scope + child scope => Won't work! Only one scope can be related to one element. Therefore these directives cannot be applied to the same element.
  • isolated scope + isolated scope => Won't work! Only one scope can be related to one element. Therefore these directives cannot be applied to the same element.

--AngularJS Comprehensive Directive API Reference -- Scope

Commands can be sent to the isolated directive with one-way bindings and the $onChanges hook.

  app.directive("myDirective", function () {
    return {
        scope: { command: '<' },
        bindToController: true,
        controllerAs: "$ctrl",
        controller: function() {
            this.$onChanges = function(changes) { 
                if ( changes.command.currentValue === 'start'
                   ) {
                    console.log(changes);
                    this.start();
                }
            };
            this.start = function() {
              console.log("Directive start invoked");
              this.started = true;
            };
        },
        template: '<p ng-if="$ctrl.started">Directive Started</p>'
    };
  });

The controller:

  app.controller('DocumentController', function() {
      var dc = this;
      dc.startDirective = function() {
        console.log("Start button clicked");
        dc.myDirCommand = 'start';
      };
  })

The DEMO on PLNKR.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.