Angular 指令:控制器中的作用域与 link 函数中的作用域有什么区别?

Angular directive: whats the difference between scope in controller vs scope in link function?

我正在学习 Angular directive,但我无法完全理解 scope 主题。假设我有这个名为 parentDirective 的自定义 directive。它有一个controller属性和一个link属性,如下:

angular.module("app").directive("parentDirective", function () {
    return {
        restrict: "E",
        templateUrl: "dirs/parent.html",
        scope:{
            character: "="
        },
        controller: function ($scope) {
            $scope.getData = function (data) {
                console.log(data);
            }
        },
        link: function (scope,elem, attrs) {
            elem.bind("click", function (e) {
                //get object here?
            });
            scope.getData = function (data) {
                console.log(data);
            }
        }
    }
});

其模板定义如下:

<p ng-click="getData(character)">
    {{character.name}}
</p>

我可以通过 $scope 变量在 controller 函数中获取 character 对象,并且我可以通过 [=] 在 link 函数中访问相同的数据16=]。这两种方法在这方面有什么区别?第二个问题,是否可以将 click 绑定到 directive 并像这样获取对象:

    elem.bind("click", function (e) {
        //get object here?
    });

范围特定于当前指令实例,并且在两个函数中是相同的对象。

在作用域上定义方法,在控制器或link函数中定义没有区别,除非存在竞争条件要求尽早定义方法。因此,在控制器中定义范围方法是有意义的。

事件处理程序与任何其他函数没有区别,它是

elem.on("click", function (e) {
  scope.$apply(function () {
    scope.character...
  });
});

scope.$apply(...) 包装器无论如何都不会受到伤害,但它的必要性取决于 scope.character.

会发生什么

指令只能有controller,不能有link。当前 Angular 版本 (1.5+) 建议使用 bindToController + controllerAs 而不是 scope 绑定作为指令和组件的共同点。

那么指令可能看起来像

restrict: "E",
template: '<p>{{$ctrl.character.name}}</p>',
controllerAs: '$ctrl',
bindToController: { character: "=" },
controller: function ($element, $scope) {
    var self = this;

    self.getData = function (data) { ... };

    $element.on("click", function (e) {
        scope.$apply(function () {
            self.character...
        });
    });
}

link函数可能显示为$postLink controller hook,但这里不需要。