Reputation: 16002
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:
Upvotes: 0
Views: 80
Reputation: 48948
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.
Upvotes: 1