我可以从指令的 link 函数设置范围 属性 吗?

Can I set a scope property from a directive's link function?

我正在制作一个包含 canvas 的指令,但我无法在所有需要的地方访问它。我目前正在指令的 link 中设置 canvas 并在其上绘制一些初始元素,但我还需要在指令的控制器中访问相同的 canvas 以更新它。目前我的指令声明如下所示:

angular.module('myModule').directive('myCanvasDirective', CanvasDirective);

function CanvasDirective() {

    var linker = function (scope, element, attrs) {
        scope.vm.ctx = element[0].childNodes[0].getContext('2d');
        //do some initial drawing using scope.vm.ctx
        //this works
    }

    return {
        priority: 1001,
        restrict: 'E',
        link: linker,
        scope: {
            displayValue: '=displayValue'
        },
        template: '<canvas id="myCanvas" width="80" height="80" />',
        controller: MyCanvasController,
        controllerAs: 'vm',
        bindToController: true
    };
};

function MyCanvasController() {
    var vm = this;

    vm.draw = function () {
        vm.ctx.strokeStyle = '#808080';
        //vm.ctx is unavailable here despite being attached to scope in linker
    };

    vm.draw();
};

如何在 MyCanvasController 中访问我的 canvas 上下文?由于这个指令将在一个页面上多次使用,这要归功于几个 ngRepeats 我不想只使用 document.getElementById().

我认为您在问题中打破了封装的一些最佳实践。您应该在包含 canvas 的指令中设置 strokeStyle。您可以通过在 link.

中传递附加属性和绑定来做到这一点

为了回答您的问题,您可以将控制器作为参数传递给指令。作为参数传递:

 <my-canvas-directive vmparent="vm"></my-canvas-directive>

的身份在您的 link 中访问
linker = function (scope, element, attrs) {
      attrs.vmparent.ctx = element[0].childNodes[0].getContext('2d');
  }

Link 函数 got a controller instance,即使它没有在 controllerAs 范围内公开。

function (scope, element, attrs, ctrl) {
    ctrl.ctx = element[0].childNodes[0].getContext('2d');
    ctrl.draw();
}

vm.ctx is unavailable here despite being attached to scope in linker

是因为控制器运行在link之前。虽然控制器 have $element local dependency, all 'when DOM element is ready' logic should be delegated to link function.

Angular 1.5 鼓励使用 component,不鼓励使用 link,原因是 Angular 2 个迁移原因。考虑在 Angular 1.5+.

中使用 $onInit 控制器方法来代替这种事情