• Для чего и как применять директивы в AngularJS?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    для чего нужны директивы


    Для всего. Директивы дают вам инструмент, позволяющий изолировать элементы UI-я в самодостаточные компоненты, расширять HTML, добавлять новые элементы со своим поведением, расширять поведение имеющихся элементов новыми атрибутами... Директивы ангуляра послужили прообразом стандарта о web-компонентов, это очень гибкая штука, которая позволяет полностью избавиться от выборок элементов и навешивания на нее логики, за счет чего код сильно упрощается.

    где их применять


    Везде где только можно, весь UI следует строить на иерархии директив, как если бы вы просто верстали. Я бы даже сказал что использовать только контроллер, как например можно увидеть в примерах для ngRoute/uiRouter и шаблон - это плохо, контроллеры и шаблоны использовать можно, но только для того что бы определить какие в рамках этого роута/стэйта будут использоваться директивы и передать туда параметры. То есть по максимуму все запихивать в директивы. Правда это может быть первое время сложно делать, потому лучше постепенно увеличивать степень дробления UI на директивы. Главная сложность сделать так, что бы директивы были независимы от контекста использования. Ну или явно определить этот контекст (параметр require директивы может определять что директива A может быть использована или должна быть использована только в контексте B). Ну и еще по началу может быть сложно определиться что должно быть в link и что должно быть в контроллере, должен ли вообще у директивы быть link или контроллер.

    ng-inject

    вы про галповский плагин или все же про ng-include? если последнее, как комбинация ng-include + ng-controller, то это тип... для ленивых. При помощи этих двух директив мы можем создать какой-то элемент, присобачить ему поведение и шаблон, да, но оно не будет изолированным, реюзать такое уже не выйдет. Если это вам надо временно, и вам лень - то можно и так, но лучше сделать полноценную директиву, тогда ее можно будет реюзать в рамках проекта и устранить дублирование. Ну и опять же, вариант с ng-include+ng-controller можно покрыть только E2E тестами, что не удобно. Директивы же просто и удобно покрываются юнит тестами, что делает поддержку системы намного проще и дешевле.

    в каком виде правильно и разумно применять директивы

    Посмотрите на polymer, это то чем должны были бы стать директивы а ангуляре (и в angular2 оно почти так), там больше ограничений и более понятно как использовать web-компоненты и как следствие - директивы.
    Ответ написан
    9 комментариев
  • Какие навыки необходимы для работы team lead?

    Вот тут всё очень хорошо разложено.
    Ответ написан
    Комментировать
  • Как в директиве получить контроллер в который она обернута?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    или если его и не нужно получать по идеологии, то почему?

    потому что это создает зависимость директивы от контекста, в котором она используется. Проследите логику

    1) работа директивы требует того что бы она была обернута в SomeControeller на уровень выше.
    2) директива становится частью SomeControeller, или если быть точным, куска view которым управляет SomeControeller.
    3) нет смысла в директиве, так как мы не можем более реюзать ее в другом месте
    4) если директива зависит от контроллера SomeControeller, почему бы не вынести из SomeControeller то что нужно директиве в ее собственный контроллер?

    как-то так. Все взаимодействие с директивой должно происходить либо через контроллеры директив (параметр require директивы), либо через атрибуты (изолированный scope, bindToController в angular 1.4). И уж тем более странно желание подменять методы контроллера из link.

    updated

    короче суть в непонимании того что есть директива как я понимаю. Директива - самодостаточная единица (самостоятельное маленькое MVC приложение). По хорошему она может зависеть только от других директив, но ей глубоко должно быть плевать где именно и как ее используют. Она выполняет свой маленький кусочек логики. Некоторые директивы выступают в роли фасадов, инкапсулируя в себе и упрощая работу с множеством директив.

    Далее, по поводу обработчиков - яркий пример директива ng-click. Эта директива выглядит как-то так:

    function myNgClick() {
        return {
            restrict: 'A',
            scope: {
                callback: "&myNgClick"
            },
            link: function (scope, el) {
                el.bind('click', function (e) {
                    scope.$apply(function () {
                         scope.callback({$event: e});
                    });
                });
            }
        }
    }


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

    link директивы нужен ТОЛЬКО для того что бы связать DOM и логику. То есть в 99% случаев в директиве будет только link или только контроллер. Оба - это уже стремно, в этом случае лучше вынести ту логику которую хочется запихнуть в link в отдельную директиву.

    контроллер (мы сейчас отойдем чуть чуть от MVC только ради того что бы упростить все) реализует всю логику (или делегирует модели). Вся логика не относящаяся к DOM а например относящаяся к обработке данных должна быть вынесена в контроллер.

    Пара слов по поводу ng-controller. Это так же директива, которая позволяет привязать к элементу какой-то контроллер. Эта штука по сути (как и ng-include в принципе) нужна только для ускорения разработки и упрощения. В целом же приложение на angular стоит воспринимать как HMVC приложение, состоящее исключительно из деревьев директив. Первый шаг на пути к web-components (по сути ангуляровские директивы послужили неплохим глотком вдохновения).

    Как-то так.
    Ответ написан
  • Как мне присваивать определенный класс в зависимости от страницы?

    mudrick
    @mudrick
    Máximo progreso hemos alcanzado en minimo seso.
    В первом комментарии всё верно и лаконично сказали — через $rootScope — я же просто разжую.

    Модуль ngRoute это просто обычный конфиг — вы в этот конфиг можете пихать всё, что вам угодно. Задайте каждой страничке уникальную айдишку или название категории странички:

    app.config(['$routeProvider',
      function($routeProvider) {
        $routeProvider.
          when('/main', {
            id: 'main',
            title: 'Главная',
            category: 'rootPage',
            templateUrl: 'mainPage.html',
            controller: 'MainPage',
          }).
          when('/powerSky', {
            id: 'powersky',
            title: 'Всем повер-скай, посоны',
            category: 'contentPage',
            templateUrl: 'template/powerSky.html',
            controller: 'PowerSky'
          }).      
          otherwise({
            redirectTo: '/main'
          });
      }]);


    Теперь, при каждой смене странички, в основном контроллере (это который общий для всех страниц сайта) пихайте в $rootScope конфиг текущей странички (текущего роута) в параметр page:

    app.controller('MainController', function($rootScope) {
      $rootScope.$on('$routeChangeSuccess', function(e, current, previous) {
        var page = current.$$route;
    
        // присваиваем глобально
        $rootScope.page = page;
      });
    });


    Теперь в HTML-шаблоне вставляйте класс для BODY:

    <!DOCTYPE html>
    <html ng-app="app">
        <head>
            <title>{{page.title}}</title>
        </head>
        <body ng-class="page.id" ng-controller="MainController">
            <main ng-view></main>
        </body>
    </html>


    Или, если у вас странички разбиты на некие общие категории, то не айдишку вставляем, а название категории (тогда меньше всяких классов нужно будет писать в CSS):

    <!DOCTYPE html>
    <html ng-app="app">
        <head>
            <title>{{page.title}}</title>
        </head>
        <body ng-class="page.category" ng-controller="MainController">
            <main ng-view></main>
        </body>
    </html>


    Ну и в стилях будет:

    body {
        &.rootPage {
            background-color: #fff;
        }
    
        &.contentPage {
            background-color: #ddd;
        }
    }
    Ответ написан
    Комментировать