调用angularjs指令函数的范围问题

scope issue calling angularjs directive function

本文关键字:范围 问题 函数 angularjs 指令 调用      更新时间:2023-09-26

我有以下控制器和指令声明。

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

如何连接文档控制器以调用指令上的方法。

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

放置区域是typescript,定义如下。

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.

文档控制器很简单。

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`);
    }
}

如果我试图在指令上使用隔离作用域,我会得到一个错误:

多个指令[ngController,dropZone(模块:panda)]询问对于新的/孤立的范围:

具有独立作用域的指令需要位于具有ng-controller指令的元素的子元素上。
<div ng-controller="DocumentController as dc" >
  <div my-directive command="dc.myDirCommand">
  </div>
</div>

ng-controller指令使用继承的作用域。具有独立作用域的指令需要位于不同的元素上。

来自文档:

通常,可以将多个指令应用于一个元素,但根据指令所需的作用域类型,可能会有限制。以下几点将有助于解释这些限制。为了简单起见,只考虑了两个指令,但它也适用于几个指令:

  • 无范围+没有范围=>两个不需要自己作用域的指令将使用其父作用域
  • 子范围+无范围=>两个指令将共享一个子作用域
  • 子范围+个子范围=>两个指令将共享一个子作用域
  • 隔离范围+无范围=>隔离指令将使用它自己创建的隔离作用域。另一个指令将使用其父指令的作用域
  • 孤立范围+子范围=>不行只有一个作用域可以与一个元素相关。因此,这些指令不能应用于同一个元素
  • 孤立范围+隔离范围=>不行只有一个作用域可以与一个元素相关。因此,这些指令不能应用于同一个元素

--AngularJS综合指令API参考——范围

命令可以通过单向绑定和$onChanges挂钩发送到隔离指令。

  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>'
    };
  });

控制器:

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

PLNKR上的DEMO。