@xbagir
web developer

AngularJS: Контроллер директивы и синтаксиc «controller as» (вопросы по style guide)?

В style guide, в разделе директив предлагается шаблон, в котором логику директивы предлагается оформлять в контроллер: шаблон

По этому поводу возникли вопросы:

1. Правильно ли понимаю, что в функции link должен размещаться код по работе с DOM, а логика в контроллере?

2. Как быть, например, с директивой которая использует ngModel ? Ведь в контроллере мы не сможем использовать ngModelController, и придется размазывать логику уже по методу link, что вроде как неверно:

angular
        .module('directives.selectBox', [])
        .directive('selectBox', selectBox);    
    
    function selectBox() {
        return {
            restrict   : 'E',
            require    : 'ngModel',
            scope      : { },
            templateUrl : 'common/directives/selectBox/selectBox.html',
            controller :  SelectBoxController,
            link: link
        };
    }


3. Почему вообще логику предлагается выносить в контроллер, ведь она должна быть в сервисе, а контроллер только для передачи параметров в сервис?

4. Насколько логичен такой подход использования контроллера, чтобы получить доступ к ngModelController ?

function link (scope, element, attrs, ngModelController){
            scope.vm = new SelectBoxController(scope, element, ngModelController);
  }
  • Вопрос задан
  • 3814 просмотров
Решения вопроса 1
ruddy22
@ruddy22
Спасение утопающих — дело рук самих утопающих
так, давай по мере поступления вопросов
1. правильно, но не совсем. логика работы с дом может так же располагаться в compile, зависит от задачи.
2-3. почему в контроллере лучше держать логику ( в разрезе директивы )? самый важный момент - в контроллер можно прокинуть сервисы и там работать с ними. в контроллере доступен $scope (так же как и в функции link). В контроллере ты не можешь ( не уверен, т.к. не пробовал ) работать с контроллером директивы ngModel (валидация, парсеры и форматеры), но ты можешь сформировать пак данных, с которыми будут работать эти (вышеперечисленные) объекты в функции link.
4. не вижу смысла в таком подходе, т.к. получается, что ты 2-й раз инитишь контроллер (через new). и я не совсем уверен, что контроллер можно использовать как Класс, для создания инстансов. у него механика работы отлична от angular.module().service()

upd
самый большой плюс всего этого действия - удобство тестирования.
отдельный контроллер проще тестировать
действия над дом проще тестировать, когда они не перемешаны с логикой контроллера
код получается тестируемый и поддерживаемый
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Суть проста. Контроллер предоставляет данные, link мэпит данные на директиву (а как, через scope, темплейты, напрямую взаимодействуя с DOM - решать вам).

То есть...

angular.module('app',  [])
  .directive('fooBar', function () {
    
    return {
      restrict: 'EA',
      requires: 'fooBar',
      controller: controller,
      link: link
    };
      
    function controller() {
      var bars = [];
      
      this.getSomeData(someOption){
            return someValueOrPromise;
      }
      
      // do soome logic with data
      
    }
    
    function link(scope, el, attrs, ctrl) {
      ctrl.getSomeData(attrs.options).then(function (data) {
            // render data
      }
    }
  });


Таким образом у вас работа с данными никак не зависит от способа вывода этих данных. Воспринимайте функцию link как слой представления.

В случае с ngModel - если честно не могу предложить сходу варианты при котором контроллер должен иметь к нему доступ. Предложите пример если не сложно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
25 нояб. 2024, в 15:52
3000 руб./за проект
25 нояб. 2024, в 15:43
1500 руб./за проект