В пользовательской директиве, какая функциональность у `controller` над` link`?

0

Пытаясь понять мои собственные директивы AngularJS, у меня есть пример, который делает все, что мне нужно, но понимаю, что при заимствовании из разных примеров я теперь могу создать функциональность для представления директивы как в контроллере, так и в ссылке,

Кажется, я мог полностью избавиться от контроллера и просто поместить все в ссылку, или есть что-то, что я могу сделать с контроллером, который я не могу сделать со ссылкой?

http://jsfiddle.net/edwardtanguay/gxr49h96/6

.directive('itemMenu', function () {

    var controller = function ($scope) {
        var vm = this;
        vm.addItem = function () {
            $scope.add();
            vm.items.push({
                'kind': 'undefined',
                    'firstName': 'Joe',
                    'lastName': 'Newton',
                    'age': Math.floor(Math.random() * 60) + 20
            });
        };

        // DOES THE SAME AS THE FUNCTION DEFINED BELOW IN LINK        
        //        $scope.convertToInternal = function(item) {
        //            item.internalcode = 'X0000';
        //            item.kind = 'internal';
        //        };        
    };

    return {
        restrict: 'A',
        scope: {
            item: '=',
            add: '&'
        },
        controller: controller,
        controllerAs: 'vm',
        bindToController: true,
        template: '<div ng-include="getTemplateUrl()"></div>',
        link: function (scope, element, attrs) {
            scope.getTemplateUrl = function () {
                switch (scope.item.kind) {
                    case 'external':
                        return 'itemMenuTemplateExternal';
                    case 'internal':
                        return 'itemMenuTemplateInternal';
                    default:
                        return 'itemMenuTemplateUndefined';
                }
            };

            scope.convertToInternal = function(item) {
                item.internalcode = 'X0000';
                item.kind = 'internal';
            };
        },
    };

})
Теги:
angularjs-directive

1 ответ

2
Лучший ответ

Вы можете найти много водянистых тиранов о контроллере против ссылки, большинство из которых содержат информацию из документации компиляции компиляции.

Отвечая на вопрос напрямую,

  • контроллеры из других модулей/файлов могут быть подключены к директиве через Angular DI с controller: 'Controller'

  • controller можно вводить зависимости, тогда как link имеет фиксированный список аргументов и получает с помощью директивных зависимостей

  • controller запускается до link, поэтому он может подготовить область для связывания или перекомпиляции элемента при некоторых условиях ASAP

  • контроллер имеет this, его внешний вид кода соответствует другому OOP-подобному ES5-коду, и методы могут быть легко перенесены между другими частями кода, например service сервис или сторонний код

  • в результате контроллеры могут быть определены как классы ES2015 или TS.

  • директивному контроллеру может require d дочерней директивой и обеспечивает удобное одностороннее взаимодействие между этими двумя

  • controller использует bindToController: true + controllerAs: 'vm' и реализует рецепт $scope.vm (особенно полезный для борьбы с прототипным наследованием JS), сохраняя this синтаксис

  • bindToController объекта bindToController предоставляет привязки атрибутов для унаследованной scope: true scope, no more $attr.$observe

  • bindToController объекта bindToController обеспечивает дополнительную детализацию для выделенной области. Если есть определенные атрибуты, которые должны быть привязаны к контроллеру и доступны с require, это можно сделать сейчас

Какой код идет к controller а для link - более тонкий вопрос.

Обычным является использование угловых контроллеров в качестве моделей представлений, как в MVVM (следовательно, соглашение controllerAs: 'vm'), поэтому, если есть задание для контроллеров (т.е. привязка служб к значениям области или настройке наблюдателей за областью), их, оставьте остальные link.

Поскольку $attrs, $element и $transclude локальные зависимости должны быть введены в контроллер явно, один может считать это признаком, чтобы пропустить их ($scope следует вводить для $scope.$ Methods, но мы просто проигнорируем этот факт),

Есть некоторые нерелигиозные проблемы, связанные с работой, которая должна выполняться по link а не по controller. require d контроллеры не были доступны в самом контроллере, поэтому такое взаимодействие с директивой происходит по link. Поскольку controller запускается на более раннем этапе компиляции, чем link, привязанные значения атрибутов пока не будут интерполированы, поэтому код, который зависит от этих значений области, переходит в link. То же самое относится к другому DOM-связанному коду, он идет по link по какой-либо причине.

Это в основном вопрос правильного стиля кода, а не реальной необходимости. Что касается кода в этом примере, вся информация о scope является удобной для контроллера, я не думаю, что эта link должна быть вообще.

  • 0
    Спасибо за этот ответ. Мой основной практический вывод - использовать контроллер вместо ссылки, который, как вы предположили, возможен в приведенном выше примере, здесь я переместил все с ссылки на контроллер, и она отлично работает: jsfiddle.net/edwardtanguay/t7oxh9e0/1

Ещё вопросы

Сообщество Overcoder
Наверх
Меню