AngularJS. Манипуляция с DOM в AngularJS


Вопрос по sql, c# &#8211 Установить имя dbo.Table в качестве имени таблицы данных

У меня есть хранимая процедура, которая возвращает 14 таблиц. Теперь в моем приложении набор данных, который содержит все dataTables с именем DataTable как table, table1, table2, table3 . и так далее. Здесь я хочу, чтобы у моего набора данных были все таблицы данных, имеющие то же имя, что и имена таблиц базы данных. Является ли это возможным ?

Я думаю, тот же вопросВот, Короткий ответ, вы не можете, извините.

Angular

AngularJS — JavaScript-фреймворк с открытым исходным кодом. Предназначен для разработки SPA — одностраничных приложений.

Фреймворк используют такие компании, как:

  • Google,
  • YouTube,
  • PayPal,
  • Weather.com,
  • VEVO,
  • Lego.com,
  • The Guardian,
  • Upwork,
  • Freelancer,
  • и многие другие.

Цель Angular — расширение браузерных приложений на основе MVC-шаблона, а также упрощение тестирования и разработки. Фреймворк работает с HTML, содержащим дополнительные пользовательские атрибуты, которые описываются директивами, и связывает ввод или вывод области страницы с моделью, представляющей собой обычные переменные JavaScript. Значения этих переменных задаются вручную или извлекаются из статических или динамических JSON-данных.

Почему AngularJS?

HTML отлично подходит для статических документов, но он мешает, когда мы пытаемся использовать его для объявления динамических представлений в веб-приложениях. AngularJS позволяет расширять словарь HTML для приложения. Angular работает с корневой проблемой фрон-енд разработки: HTML не предназначен для создания динамических представлений.

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

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

Связь с сервером

AngularJS предоставляет встроенные сервисы поверх прямых http/https запросов на серверы с использованием сторонних библиотек. Обещает дальнейшее упрощение кода путем обработки асинхронного возврата данных. Angular придерживается MVC-шаблона проектирования и поощряет слабую связь между представлением, данными и логикой компонентов. Используя внедрение зависимости, Angular переносит на клиентскую сторону такие классические серверные службы, как видозависимые контроллеры. Следовательно, уменьшается нагрузка на сервер и веб-приложение становится легче.

Двустороннее связывание данных

Связывание данных — это автоматический способ обновления представления всякий раз, когда изменяется модель, а также обновление модели всякий раз, когда изменяется представление. Это очень удобно, потому что оно устраняет манипуляции DOM из списка вещей, о которых нужно беспокоиться. Двустороннее связывание данных в AngularJS уменьшает количество кода, освобождая сервер от работы с шаблонами. Вместо этого, шаблоны отображаются как обычный HTML, наполненный данными, содержащимися в области видимости, определённой в модели. Angular следит за изменениями в модели и изменяет раздел HTML-выражения в представлении через контроллер. Кроме того, любые изменения в представлении отражаются в модели. Это позволяет обойти необходимость манипулирования DOM и облегчает инициализацию и прототипирование веб-приложений.

Шпаргалка по AngularJS

Эта статья позволит быстро освоить основы JavaScript-фреймворка AngularJS.

Другие статьи по AngularJS:

С чего начать

    1. Подключаем скрипты фреймворка на страничку (взять можно здесь), как минимум, Вам потребуются: angular.js, angular-route.js, angular-locale_ru-ru.js. В рассматриваемом здесь приложении мы используем анимацию, поэтому добавим еще и angular-animate.js.
    2. Создаем app.js — это будет «точка входа» в приложение angular. Внутри объявляем корневой модуль приложения и его зависимости, конфигурируем роуты; если нужно, определяем функцию, которая выполнится при старте приложения, и оборачиваем все это в вызов анонимной функции, «чтобы наружу не торчало ничего»:

    Рассмотрим код подробнее.
    Конструктор модуля принимает два аргумента — имя модуля и массив имен модулей, от которых он зависит.
    Функция config выполняется в момент старта приложения, здесь, во-первых, задается роутинг, а во-вторых, конфигурируются сервисы, предоставляемые провайдерами… ок, мы еще вернемся к этому.
    При конфигурации маршрутов мы задаем url шаблона, который нужно использовать для рендеринга (также можно прямо на месте строкой передать inline-шаблон, только не в templateUrl , а template , но лучше так не делать вообще никогда). Часто здесь же параметром controller обычно задается контроллер (сюрприз!), который будет использоваться для взаимодействия с шаблоном, но мы этого делать не будем, позже объясню почему.
    Функция run выполняется после загрузки всех модулей, нам нечего делать на этом этапе, поэтому мы ничего не делаем в ней (то есть ее можно было вообще не передавать в .run()). Но, к примеру, здесь можно получить текущего пользователя из сессии и сохранить его $rootScope.
    А что за $rootScope ? Для начала стоить сказать, что такое $scope . Скоуп — это модель, «клей» между логикой и шаблонами. Скоупы компонуются и наследуются, образуя древовидную структуру, в контексте скоупов выполняются выражения в шаблонах, скоуп может следить ( $watch ) за выражениями (а также функциями, коллекциями, переменными) и бросать события. Все, что есть в скоупе — доступно в связанном с ним шаблоне и в его дочерних скоупах. На самом деле, я сейчас просто пересказал вступление к статье по скоупам из официальной документации, поэтому советую все же заглянуть в первоисточник.
    Теперь, когда мы разобрались (разобрались же?), что такое скоуп, можно пояснить, что такое $rootScope — это, как не трудно догадаться, родительский скоуп всех скоупов в приложении. Ключевые моменты:

    • Одна штука на приложение
    • Доступен из любого места приложения, достаточно внедрить $rootScope
    • Ловит все события
    • Соответственно, события, брошенные им, дойдут до любого дочернего скоупа
    • Превращается в помойку при злоупотреблении
  1. На страничке приложения в тэг html или body добавляем директиву ng-app=»dummy» тем самым заявляя, что внутри этого тэга будет работать angular-приложение dummy, точка входа в которое описана в одноименном модуле.
  2. Где-то внутри body добавляем блок с директивой ng-view — здесь будут рендериться наши шаблоны в соотстветствии с текущим роутом.

Это основные приготовления для angular-приложения. Теперь, прежде чем начать штамповать контроллеры и сервисы, замолвим слово про структуру приложения.

Структура приложения

Следуя рекомендациям разработчиков Angular, структура должна выглядеть примерно так:

Корневая директория называется по имени самого приложения, в ней лежат: контроллер верхнего уровня (app-controller.js), базовые стили приложения (app.css), дефолтный шаблон (app.html) и главный модуль приложения (app.js).

  • разделы приложения (foo и bar), каждый со своими контроллером, шаблоном и стилями;
  • компоненты: здесь храним директивы, сервисы и т.д., которые разделяются по функционалу/сущностям, к которым они относятся (например, все, что имеет дело с message, лежит в одной директории), каждая директива лежит отдельно от другой;
  • конфигурация — здесь, соответственно все constant и value сервисы (url-config.js) и модуль (config.js), в котором все это содержится.

Предлагаемая структура — иерархическая, например, если раздел foo у нас сильно усложнится и мы решим разбить его на части, то файлы дочерних разделов уже будут храниться в поддиректориях foofoo/customer«, «foo/supplier«).

Структура модулей соответствует файловой, то есть сервисы MessageManagerFactory и MessageService содержатся в модуле dummy.message , директива MessageList — в модуле dummy.message.messageList , директива MessagePoster — в модуле dummy.message.messagePoster (да, каждая директива хранится в собственном модуле).

Контроллер

Контроллер — это функция-конструктор, которая используется для «оживления» шаблона. Типичный сценарий использования: шаблон привязывают к контроллеру на этапе конфигурации, в контроллер передают $scope , набивают его под завязку всеми данными и логикой, которые используются на странице, а потом пытаются совладать с 600-строчным чудовищем. Так делать не надо.
Во-первых, $scope нужно использовать только тогда, когда без него не обойтись вообще никак, то есть вызов $watch , $emit , $broadcast и т.д. Все функции, объекты и поля лучше держать в экземпляре контроллера:

В данном случае, в конструкторе мы инициализируем поле saidHi , создаем экземпляр MessageManager , в котором инкапсулируем работу с сообщениями, а также создаем пустой массив для хранения сообщений. Функции, которые будем использовать в шаблоне, выносим в прототип.

Убирая код, работающий с сообщениями в MessageManager , мы не только уменьшаем количество кода в контроллере (что само по себе хорошо), но и избавляемся от зависимостей, которые этот код может за собой тащить. (Да, конкретно для данного случая — это overkill, MessageManager всего-то умеет дергать сервис для отправки/получения/удаления сообщений и выполняет простые callback’и, но идея, думаю, ясна).

$scope же здесь используется только для задания обработчика события message.new.local (мы ждем, что один из дочерних контроллеров или директив может создать новое сообщение).

В шаблоне все это используется так:

AppController объявлен как «главный» контроллер приложения, поэтому он будет доступен везде как appCtrl . Это удобно, но так же, как и с $rootScope этим лучше не злоупотреблять. В данном приложении мы используем эту возможность для доступа к списку сообщений в дочерних контроллерах.

Использование в шаблоне членов экземпляра контроллера, а не скоупа, защищает нас от трудноуловимых багов — мы всегда точно знаем, что именно будет использоваться. Кроме того, двухсторонний биндинг примитивов в дочерних скоупах будет работать корректно без дополнительных оберток.

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

В самом шаблоне, все достаточно просто: показываем «приветствие» из поля greeting , которое меняется по клику на кнопку «Say Hi». Далее у нас подключена директива messageList для вывода списка сообщений. Для запросов к серверу для получения, отправки и удаления сообщений служат три кнопки «Save new», «Get all», «Delete all», а статус выполнения запроса выводится чуть ниже.

Директивы

Директива — это независимый компонент, предназначенный для многократного использования. Стоит заострить на этом внимание, т.к. не нужно создавать директиву на каждую форму приложения — если форма специфична для конкретной страницы, и вы сомневаетесь, что она может понадобиться где-то еще — не надо делать из нее директиву. Если нужно разгрузить шаблон и контроллер — просто вынесите код в частичный шаблон и напишите для него отдельный контроллер.

Директивы можно разделить на два типа: изменяющие поведение элемента (draggable, collapsable и т.д.) и кастомные ui-компоненты (контрол для пагинации, календарь, модальное окно).

Директива должна делать одну и только одну вещь, не нужно собирать мега-комбайны, делающие все на свете.

Рассмотрим код простой директивы, оборачивающей элемент в «гармошку» — collapsable:

Для создания директивы нужно вызвать метод directive() у модуля, передав туда имя директивы и массив с внедряемыми зависимостями и, собственно, с конфигурационной функцией, определяющей поведение директивы. В данном случае зависимостей нет, поэтому в массиве всего один элемент — функция.

Для данной директивы нам потребовалось задать всего четыре параметра:

1) restrict — определяет, в качестве чего можно использовать директиву, возможные варианты: A — атрибут, E — элемент, и, с недавних пор, С — класс.

2) link — основная функция для «поведенческих» директив, здесь мы имеем доступ к $scope , jqueryLite-обертке элемента, к которому директива применена, и его атрибутам (в виде хэша). link выполняется после того, как манипуляция с DOM (для этой директивы) была завершена.

3) transclude — с этим все не так просто. Если установлен в true , изменяет скоуп директивы так, что его содержимое замещается содержимым родительского скоупа. Таким образом, если и в скоупе директивы, и в скоупе контроллера задать одноименные поля, в шаблоне директивы использоваться будет поле из скоупа контроллера. Этот параметр следует использовать только вместе c директивой ng-transclude , для подстановки фрагмента DOM извне в «тело» директивы — вставленный фрагмент шаблона не потеряет доступ к переменным в родительском $scope, если он их использовал, и нам не придется передавать их в качестве параметра (ну и если не выставить trancslude в true , у вас вылетит Error: orphane ng-transclude directive ). В данном случае, список сообщений (message-list) будет «подставлен» внутрь блока div в шаблоне директивы с атрибутом ng-transclude (при этом все текущее содержимое div’a будет удалено).

4) templateUrl — url, по которому будет запрошен шаблон для директивы.

Теперь рассмотрим директиву с изолированным скоупом — messageList :

Здесь в конфиге директивы три новых параметра:

  1. scope — если сюда передать хэш (даже пустой), у директивы будет изолированный скоуп (неизолированный скоуп прототипически наследует родительский). Заполняется этот хэш таким образом, что ключ — это название свойства у скоупа, а значение — имя атрибута, значение которого будет связано с этим свойством. На то, как именно будут «забиндены» значения атрибутов на свойства в скоупе, влияют префиксы перед именем атрибута:
    • @ — значение из атрибута будет передано в свойство скоупа директивы строкой.
    • & — свойство директивы будет функцией, интепретирующей выражение, содержащееся в атрибуте. Именно этот префикс используется здесь. Таким образом, вызов $scope.getMessages() вызовет appCtrl.getMessages() и вернет массив сообщений.
    • = — свойство скоупа директивы будет «забиндено» на объект, имя которого указано в атрибуте, т.е. будет создана двухсторонняя связь.
    • ? — флаг необязательности наличия значения, используется в дополнение к другим.
  2. controller — имя контроллера, который будет прикреплен к шаблону директивы.
  3. replace — если установлен в true, блок директивы будет заменен контентом шаблона директивы.

В контроллере директивы можно также увидеть использование функции $watchCollection — angular будет следить за состоянием массива или хэша, если его состояние изменится, будет вызвана callback функция с двумя параметрами — newValue и oldValue .

В шаблоне мы выводим список сообщений в messages с помощью ng-repeat , при этом выполняется сортировка по полю, имя которого хранится в sortBy , sortBy при этом задается из select’a.

Для каждого сообщения мы выводим дату, при этом форматирование выполняется с помощью фильтра angular’a date .

Сервисы

Видов сервисов в angular — пять штук:

Неизменяемый объект или примитив. Может быть использован на этапе конфигурации.

  • value — изменяемый объект или примитив. Не может быть использован на этапе конфигурации.
  • factory — сервис, возвращающий какой-либо объект (неважно какой). Приведем фрагмент фабрики MessageManagerFactory :

    В фабрике определена функция-конструктор объектов MessageManager , заданы методы прототипа MessageManager , приватные функции вынесены в хэш _private , и объявлена «статическая» приватная функция _filterNew (статическая в том смысле, что не обращается к членам экземпляра MessageManager ). На выходе фабрики — литерал объекта с единственным методом — make .
    service — отличается от фабрики тем, что при первом использовании функция будет использована как конструктор объекта. Приведем код нашего сервиса сообщений:

    В сервисе определяется конструктор объектов Message (возможно, не самое лучшее решение, да); url для вызова api сервера берется из constant сервиса urlConfig ; для экземпляра самого сервиса определены методы для вызова сервера ( post , delete , get ), метод для создания экземпляра Message и метод для конвертации из json, пришедшего с сервера, в объект Message (все сообщения с сервера конвертируются, таким образом, все наши сообщения в angular-приложении — экземпляры Message ).
    provider — сервис, который можно использовать, если требуется некая конфигурация при старте приложения. В таком сервисе должна быть определена функция $get() , результат выполнения которой будет предоставлен клиенту сервиса. В сам провайдер можно добавить какие-либо функции для его конфигурации:


    Создав таким образом провайдер, мы можем использовать его в функции configure на старте приложения и задать значение параметра someConfigurableParam .

    Подробнее о наследовании $scope

    Скоупы в большинстве случаев ( ng-include , ng-switch , ng-controller , ng-transcluded , директивы с параметром scope: true ) наследуются прототипически (не уверен, что есть такое слово), из чего следует:

    • Изменение примитива в дочернем скоупе создает новое поле в нем, не оказывая эффекта на этот примитив в родительском скоупе.
    • Изменение поля в объекте в дочернем скоупе изменяет это поле в соответствующем объекте в родительском скоупе.
    • Изменение ссылки на объект в дочернем скоупе создает новую ссылку в нем, ссылка в родительском скоупе не изменяется.

    Стоит отметить, что ng-repeat создает новый скоуп для каждой итерации, значения полей которого копируются из соответствующего элемента итерируемой коллекции родительского скоупа. Поэтому не стоит использовать массивы примитивов в ng-repeat , разве что только для read-only.

    Скоупы не наследуются прототипически в следующих случаях:

    1. Создание директивы с параметром scope: false (по умолчанию). В данном случае, директива использует родительский скоуп как свой собственный, что естественно нежелательно использовать, т.к. может привести к трудноуловимым багам.
    2. Создание директивы с параметром scope: <> . Как уже говорилось выше, создает изолированный скоуп. Поля такого скоупа никак не связаны с родительскими, однако доступ к его полям (родителя) можно получить через атрибуты-параметры директивы (используя биндинги ‘@’, ‘&’ и ‘=’).

    Доступ к родительскому, соседнему или дочерним скоупам можно получить с помощью следующих свойств: $scope : $parent , $$nextSibling , $$childTail и $$childHead .

    Подробнее обо всей этой кухне можно почитать здесь.

    О применении $scope.$apply()

    Вызов этой функции заставляет angular обновить состояние шаблона в соответствии c актуальным состоянием шаблона, однако, если вам пришлось использовать это — скорее всего, вы сделали что-то неправильно: использовали setTimeout вместо $timeout , setInterval вместо $interval , element.on(‘click’) вместо ng-click и т.д. В редких случаях использование $apply оправдано — необходимо изменить модель извне angular -приложения, но мне пока не приходилось с таким сталкиваться. В таких случаях использовать $apply нужно следующим образом (украдено отсюда):

    И далее вызываем safeApply() везде, где нам требуется вызов $apply() .

    Ссылка на репозиторий демо-приложения на гитхабе: ng-help.

    DOM-манипуляция в компоненте AngularJS 1.5

    Я попытался обернуть голову вокруг концепции компонента AngularJS, и я начал понимать принцип, но когда я попытался его практиковать, я нашел пример, когда не знаю, как реализовать это с компонентом.

    Мне нужно реализовать линейный прогресс, у него есть шаблон, поэтому логически должен быть компонент, а не директива, но я не могу найти способ делать манипуляции с DOM в компоненте, и кажется странным иметь директиву внутри такой маленький компонент. Вот основная реализация директивы:

    Топ-пост этого месяца:  Страница wordpress admin изменение CSS стилей

    JS

    HTML

    CSS

    Итак, возможно, я понял принцип компонента неправильно, но я действительно много искал его и думал, что я понял принцип, прежде чем я столкнулся с этим примером.

    Итак, мой вопрос: могу ли я каким-либо образом манипулировать DOM в компоненте, и если ответ отрицательный, каков способ реализации этой директивы в компоненте (и он подходит вообще)? Я не считаю, что добавление директивы к компоненту только для изменения CSS — это подходящий выбор, поэтому я застрял.

    Создан 13 сен. 16 2020-09-13 18:09:03 kemsbe

    не понадобилось бы манипуляции с dom или ни одного из js в вашей ссылке, если бы вы использовали ‘ng-style’ – charlietfl 13 сен. 16 2020-09-13 18:20:47

    @charlietfl oops, похоже, что я действительно могу использовать ng-style и передавать значение там, теперь это выглядит очевидным , спасибо, я думаю, вы можете опубликовать его как ответ – kemsbe 13 сен. 16 2020-09-13 18:37:57

    Вам нужно сделать работу своей директивой или вам нужен новый компонентный подход? Проверенный ответ остается директивой и не отвечает на вопрос – Joaozito Polo 13 сен. 16 2020-09-13 19:19:19

    @JoaozitoPolo Мне нужен компонентный подход, но, как я понял, мне все равно нужно использовать внутренний компонент директивы, ng-style или custom, я прав? – kemsbe 13 сен. 16 2020-09-13 19:39:20

    3 ответа

    Чтобы устранить ваше замешательство о компоненте против директивы, чтобы использовать один над другим — это вопрос того, как вы разрабатываете свое приложение.

    Если вы предпочитаете использовать архитектуру MVC (MVVM, MVW, MV *), нет смысла иметь компоненты. Вы просто создаете представления, контролируемые контроллерами и директивами, которые будут изменять или управлять некоторыми элементами DOM.

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

    Начиная с 1.5, директива подходит очень близко к компонентам. Вы можете избавиться от области действия, создать контроллер . и т. Д., У вас есть только немного более шаблонный код для записи.

    Если вы хотите, чтобы ваше приложение следит за архитектурой (реагируйте, веб-компоненты, угловые2 . и т. Д.), Тогда все в приложении должно быть компонентом. (логин, навигация, нижний колонтитул . и т. д.), а компоненты могут иметь меньшие компоненты. (компонент загрузки файла может содержать компонент индикатора выполнения).

    Когда требуется больше элементов управления, то при использовании директив. Если для вас нет действующей угловой директивы (ngStyle, ngClass, ngShow . и т. Д.), Вы создаете свои. (Вы хотите вход, чтобы получить фокус автоматически, вы можете создать директиву)

    Чтобы ответить на этот прогресс бар вещь, это то, как я хотел бы написать свой компонент:

    PS: Стиль css был скопирован с css-tricks, чтобы сэкономить время.

    Создан 13 сен. 16 2020-09-13 19:58:35 gyc

    . Спасибо за такой полный ответ, так как теперь я понимаю, угловой 1.x не совсем разработан для архитектуры компонентов, это больше о архитектуре MV *, правильно ? А для архитектуры компонентов такие рамки, как реагирующие или угловые 2, более подходят, я прав? Итак, для углового 1.x лучше придерживаться директив и использовать компоненты только в том случае, если необходимо отделить часть приложения, верно? – kemsbe 13 сен. 16 2020-09-13 20:24:44

    @IlyaIlin no, от 1.5 и вы можете создавать приложения на основе 100% компонентов. Это зависит только от вас (или вашего босса). При работе каждое приложение, которое мы начинаем в этом году, будет основано на компонентах (angular2 не готов к выпуску). Наша интрасеть составляет 100% с угловыми 1,5 компонентами. Некоторые команды более старой школы, и мы придерживаемся MVC в некоторых других проектах. (ничто не шокирует это). Это вопрос мнения. Компоненты более современные (мода), но код действительно чище, чем у нас с MVC. – gyc 13 сен. 16 2020-09-13 20:32:55

    Большое вам спасибо, вы действительно сделали это более понятным для меня – kemsbe 13 сен. 16 2020-09-13 20:34:58

    Манипуляция DOM в сервисах AngularJS

    хорошо известно, что вы должны манипулировать элементами DOM внутри директив при использовании AngularJS.

    однако, похоже,что в некоторых случаях использования допустимо манипулировать DOM внутри службы. Миско Хевери говорит об этом!—3здесь. Вы также можете найти пример в Bootstrap UI Dialog.

    объяснение Миско довольно расплывчато, поэтому мне было интересно, как вы определяете, когда вам нужно поместить DOM внутри службы вместо директива.

    5 ответов

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

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

    всплывающие окна могут быть другими ситуация, когда мы могли бы использовать службу, но, в отличие от диалога, всплывающее окно прикреплено к узлу DOM. Так что даже это немного серая область.

    Итак, основной и простой тест: «может ли этот бит кода манипуляции DOM быть прикреплен к узлу DOM?- Если да, то директива. Если нет, то обслуживание.

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

    хотя я думаю, что Ганарадж описал, что Миско говорил хорошо, вы могли бы (и потенциально должны) утверждают, что код манипуляции DOM для модального диалога (например) can быть помещенным в узел DOM.

    один подход состоит в том, чтобы иметь директиву диалога, прикрепленную к DOM все время, а затем использовать ng-show условно показать его. Затем вы можете связаться с модальным диалогом, используя либо $rootScope , или лучше: сервис.

    I на самом деле предпочитаю этот подход, потому что он чувствует себя «правильным» — служба обрабатывает передачу данных, а директивы взаимодействуют с сервисом, чтобы убедиться, что он отображается таким образом, который имеет смысл для пользователя.

    но я думаю, что тот факт, что Миско не особенно ясно об этом показывает, что это довольно субъективно. Делайте то, что кажется вам наиболее разумным.

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

    У меня есть директивные элементы, которые реагируют на положение мыши глобально (например, они перемещаются или изменяются каким-то образом на основе положения мыши). Существует неопределенное число этих элементов, и они не относятся к какому-либо конкретному местоположению в приложении (поскольку это элемент GUI и может относиться к любому контейнеру в любом месте). Если бы я придерживался строгого правила угловой «логики dom только в директивах», это было бы менее эффективно, потому что все элементы разделяют логику, относящуюся к разбору позиции мыши (эффективно), которая вращается вокруг окна.метод requestAnimationFrame клещей.

    Если бы я связал эту логику в директиву, у меня был бы цикл listener/raf, привязанный к каждому единичный случай. Хотя он все еще был бы сухим, он не был бы эффективным, так как при каждом движении мыши вы бы запускали точно такой же слушатель, который возвращал бы точно такой же результат для каждого отдельного элемента.

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

    помните, в то время как Angular дает очень хорошие советы о том, как структурировать ваш код, это не делает его пуленепробиваемым никаким жестким и быстрым правилом, поскольку он не может охватывать все случаи использования. Если вы видите дыру, где «лучшие практики», похоже, терпят неудачу, это потому, что вы на самом деле правильного понимания лучшие практики, и теперь вы нашли причину, чтобы нарушить правила нарочно.

    Это всего лишь мои 2 цента!!

    один недостаток использования метода манипуляции DOM, основанного на изменении переменной (т. е. ng-show=»isVisible» ) заключается в том, что манипуляция DOM происходит после следующего цикла» javascript turn » (когда isVisible обновляется). Возможно, Вам потребуется обновить DOM сразу.

    например, общий сценарий отображает «счетчик» во время переходов к новому маршруту / состоянию. Если бы вы установили $scope.isVisible = true на $routeChangeStart / $stateChangeStart событие, а потом $scope.isVisible = false на $routeChangeSuccess / $stateChangeSuccess событие, вы никогда не увижу вашего ng-show , поскольку все изменение маршрута / состояния происходит в течение одного поворота javascript. Было бы лучше использовать .show() и .hide() в этих событиях, так что вы действительно видите счетчик.

    чтобы вернуть все это и сделать его актуальным для вопроса OP — в ситуации, когда манипуляция DOM является модальным отображением» spinner», я бы сделал это во время службы, и я бы сделал это с помощью прямых методов манипуляции DOM, а не полагаясь на модель изменение.

    Я согласен с @dudewad. В конце концов, услуга (фабрика, поставщик, значение) — это просто шаблон модуля angular с ограничением реализации в виде синглтона. Я думаю, что важно, чтобы вы получили доступ к DOM через элемент, который передается в функцию ссылки директивы, а не с помощью документа или других глобальных подходов. Однако я не думаю, что важно, чтобы логика, которую вы применяете к элементу dom, который вы получаете от директивы, жила в том же модуле. По причинам SRP может быть выгодно разбить код немного, используя службу, поскольку у вас может быть особенно сложный кусок логики, который имеет больше смысла иметь сфокусированный тест, или вы можете использовать логику в более чем одной директиве, как указано @dudewad.

    Манипулирование DOM в angularJS: лучшая практика?

    Мы строим большой веб — приложения с использованием AngularJS . Мы используем пользовательские директивы много для различных случаев. Когда дело доходит до делать манипуляции DOM, связывающее событие, и т.д. . Это бывает, что мы определяем функции , которые манипулируют DOM в пользовательской директиве link функции, но мы называем его из контроллера (мы определяем функции в $scope поэтому он может быть доступен данным контроллером). Я думаю, что угловой способ сделать это, был бы определить отдельную пользовательскую директиву для каждой функции и использовать его непосредственно из шаблона, но в нашем случае я не знаю, до какой степени это будет комфортабельным сделать так, мы уже много пользовательской директивы, так что это пЛОХО, чтобы делать то, что мы делаем (определение функции, манипулировать DOM в директиве и вызывать его из контроллера), делает это даже имеет смысл или это просто, как мы манипулируя DOM в контроллере ? Для нас это своего рода разделения концерна, мы никогда не определим функцию, которая манипулировать DOM в контроллере, только в директиве, но вызвать его из контроллера не кажется, так хорошо, не так ли?

    Пример, показывающий, как наш обычай директива выглядеть следующим образом:

    Я думаю, что «не манипулировать DOM из контроллеров» мантра назад от дней, когда директивы в основном / используются только ссылка функции (или контроллеров директивы, где только способ сообщаться с другими директивами).

    В настоящее время предлагается лучшая практика заключается в использовании «компонентов» (которые могут быть реализованы с помощью директив), где в основном вся логика директивы уходит в контроллере. (Обратите внимание, например, что в угловых 2 нет, связывающей функции и каждый компонент / директива в основном класс / контроллер (плюс некоторые метаданные).)

    В этом контексте я считаю , что это прекрасно , чтобы манипулировать DOM в директивы шаблона изнутри директивы контроллера.

    Идея заключается в том, чтобы сохранить ваши шаблоны / HTML декларативными. Сравните следующие фрагменты:

    В первом (плохой) , например, myComponent будет иметь различное поведение / внешний вид в зависимости от того, где в DOM оказывается (например , это под SomeController ?). Что более важно, это очень трудно выяснить , что другие (не связанные) часть может быть изменение myComponent «s поведение / внешний вид.

    Во втором (хорошо) , например, myComponent поведение «s и внешний вид будет соответствовать через приложение , и это очень легко узнать, что это будет: я просто смотреть в определении директивы (одно место).

    Есть несколько предостережений, хотя:

    Вы не хотите смешивать DOM код манипуляции с другой логикой. (Это сделает ваш код менее ремонтопригодны и сложнее тестировать).

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


    Как правило, вы не хотите, чтобы запустить манипуляции DOM, когда контроллер не конкретизируется в контексте директивы, так как это будет означать, что вы всегда нужен скомпилированный шаблон для того, чтобы протестировать контроллер. Это нежелательно, так как это делает модульные тесты медленнее, даже если вы только хотите, чтобы проверить другие части логики контроллера, которые не являются DOM / HTML связаны.

    Так что мы можем сделать ?

    Изолировать ваш DOM-код манипуляции в выделенной функции. Эта функция будет вызываться при необходимости (см ниже), но все взаимодействия DOM будет находиться в одном месте, что делает его легче рассмотреть.

    Выставляет эту функцию как метод контроллера и вызвать его из функции связующей вашей директивы (а не во время инициализации контроллера). Это гарантирует, что DOM будет в нужном состоянии (если это необходимо), а также развязка «автономная» контроллер конкретизация от манипуляции DOM.

    Что мы получаем:

    Если ваш контроллер конкретизируется как часть директивы компиляции / компоновки, метод будет называться и DOM будет манипулировать, как и ожидалось.

    В юнит-тесты, если вам не нужна логика манипуляции DOM, вы можете создать экземпляр контроллера непосредственно и проверить это бизнес-логика (независимо от любого DOM или компиляции).

    У вас есть больше контроля над тем, когда манипуляция DOM происходит (в единичных тестах). Например , вы можете создать экземпляр контроллера непосредственно, но по- прежнему проходят в $element , делать какие — либо утверждения , вы можете захотеть сделать, то вручную вызвать метод DOM-манипулирования и утверждают , что элемент преобразуется правильно. Кроме того , легче пройти в издевался $element и такие вещи , как добавление слушателей событий, без того , чтобы создать настоящий DOM.

    Недостаток этого подхода (обнажая метод и назвав его из функции связующей), является дополнительным шаблонным. Если вы используете Угловое 1.5.x, вы можете избавить шаблонный с помощью контроллера директивы жизненного цикла крючков (например , $onInit или $postLink ), без необходимости иметь функцию связывания, просто разжиться контроллер и вызова метода на нем. (Bonus особенность: Используя синтаксис 1.5.x компонента с жизненным циклом крючками, облегчила бы перейти на угловой 2.)

    манипуляция DOM в AngularJS 1.5 Компонент

    December 2020

    4.5k раз

    Я пытался обернуть мою голову вокруг концепции компоненты AngularJS и я вроде начал понимать принцип, но когда я пытался практиковать его, я нашел пример, когда я не знаю, как реализовать его с компонентом.

    Мне нужно реализовать линейную прогрессбар, он имеет шаблон, поэтому логически должен быть компонентом, а не директива, но я не могу найти способ сделать DOM манипуляции в компоненте, и это кажется странным, чтобы иметь директиву внутри такого маленького компонента , Вот основная реализация директивы:

    JS

    HTML

    CSS

    Так, может быть, я понял принцип компонента неправильно, но я действительно гугле много об этом и думал, что я понял принцип, прежде чем я столкнулся этот пример.

    Так что мой вопрос: Могу ли я управлять DOM в компоненте в любом случае, и если ответ нет, что это способ реализовать эту директиву в компоненте (и это подходит вообще)? Я не чувствую, что добавление директивы к компоненту просто изменить некоторые CSS является подходящим выбором, поэтому я застрял.

    3 ответы

    Я сделал подобный компонент, например. Посмотрите на стиль определения замены:

    Согласно документации ANGULAR, любые манипуляции с DOM должны быть сделаны с помощью директив. Это может быть большая работа сейчас, но вы всегда можете повторно использовать директиву в рамках вашего проекта.

    «На высоком уровне директивы являются маркерами на DOM элемента (например, атрибут, имя элемента, комментарий или класс CSS), которые говорят HTML компилятор AngularJS (в $ компиляции) приложить определенное поведение к этому DOM элемента (например, с помощью прослушивателя событий ), или даже преобразовать элемент DOM и его детей «.

    вот как вы будете изменять CSS с помощью директивы

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

    Если вы предпочитаете придерживаться к MVC (MVVM, MVW М.В. *) архитектуры, имеет мало смысла иметь компоненты. Вы просто создавать представления, управляемые контроллерами и директивами, которые будут изменять или контролировать некоторые элементы DOM.

    В MV * приложении есть некоторые случаи , когда вы действительно хотите , чтобы отделить блок от остальной части страницы и даже сделать его повторно. Вы все еще можете сделать компонент для него , но он имеет больше смысла в этой архитектуре придерживаться директив.

    С 1.5, директива очень близко к тому, что компоненты. Вы можете избавиться от рамки, создать контроллер . и т.д., вы просто немного более шаблонный код писать.

    Если вы хотите , чтобы ваше приложение , чтобы следовать компонентной архитектуре (среагировать, веб — компоненту, angular2 . и т.д..) , То все , что в заявке должно быть компонентом. (Логин, навигация, сноска . и т.д.) и компоненты могут иметь меньшие компоненты. (компонент загрузки файла может содержать прогресс бар компонент)

    Когда более контроль над DOM — элементов требуется, это при использовании директивы. Если ни одна из существующей угловой директивы работает для вас (ngStyle, ngClass, ngShow . и т.д.) . Вы не создадите ваш. (Вы хотите вход , чтобы получить фокус автоматически, вы можете создать директиву)

    Чтобы ответить на этот прогресс бар вещь, это то, как я хотел бы написать свой компонент:

    PS: Стиль CSS был скопирован с CSS-уловок , чтобы сэкономить время.

    Паттерны в AngularJS

    Краткий обзор

    Один из лучших способов изучить, что то новое, это увидеть, как в нем используются уже знакомые нам вещи. Эта статья не намерена ознакомить читателей с проектированием или шаблонами проектирования. Она предлагает базовое понимание концепций ООП, шаблонов проектирования и архитектурных шаблонов. Цель статьи описать, как различные конструкции программного обеспечения и архитектурные шаблоны используются в AngularJS и написанных на нем SPA.

    Топ-пост этого месяца:  Урок 8. Получение правильных ответов

    Введение

    Краткий обзор AngularJS

    AngularJS это JavaScript веб фреймворк разработанный Google. Он намерен обеспечить прочную основу для разработки CRUD SPA. SPA загружается только один раз и не требует перезагрузки страницы при работе с ним. Это означает, что все ресурсы приложения (data, templates, scripts, styles) должны быть загружены при загрузке главной страницы или по требованию. Поскольку большинство CRUD приложений имеют общие характеристики и требования, AngularJS намерен предоставить их оптимальный набор из коробки. Вот несколько важных особенностей AngularJS:

    • two-way data binding (Двустороннее связывание данных)
    • dependency injection, DI (Внедрение зависимостей)
    • separation of concerns (Разделение ответственности)
    • testability
    • abstraction

    Разделение ответственности достигается путем деления каждого AngularJS приложения на отдельные компоненты, такие как:

    • partials
    • controllers
    • directives
    • services
    • filters

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

    Partials

    Partials это HTML строки. Они могут содержать AngularJS выражения внутри элементов или их атрибутов. Одним из преимуществ AngularJS перед другими фреймворками, является то, что шаблоны AngularJS не находятся в промежуточном формате, который должен быть преобразован в HTML (как например в mustache.js)

    Вначале каждое SPA загружает файл Index.html. В случае с AngularJS этот файл содержит набор стандартных (и не очень) HTML атрибутов, элементов и комментариев, которые настраивают и запускают приложение. Каждое действие пользователя требует загрузки других partials (HTML строк или файлов с кусками HTML) или изменение состояния приложения, например через связывание данных (data binding) предоставленное фреймворком.
    Пример partials:

    Вместе с выражениями AngularJS, partials определяют, какие действия должны быть выполнены для взаимодействия с пользователем. В примере выше значение атрибута ng-click означает, что метод changeFoo() будет вызван из текущего scope.

    Controllers

    Контроллеры в AngularJS – это обычные функции, которые позволяют обрабатывать взаимодействие пользователя и приложения (например события мыши, клавиатуры и тд.) путем добавления методов в scope. Все внешние зависимости для контроллеров предоставляются при помощи механизма DI в AngularJS. Контроллеры также отвечают за взаимодействие моделей с partials путем добавления данных в scope. Это можно рассматривать как модель представления (view model).

    Например, если мы подключим контроллер представленный выше в предыдущую секцию, то пользователь будет иметь возможность взаимодействовать с приложением несколькими способами:

    1. Изменение «foo» путем ввода данных в поле ввода. Это немедленно отразится на значении «foo» из-за двустороннего связывания данных.
    2. Изменение значения «foo» нажатием на кнопку с названием «Click me to change foo!»

    Все пользовательские элементы, атрибуты, комментарии или классы могут быть директивами AngularJS (если они предварительно определены).

    Scope

    В AngularJS scope является JavaScript объектом, который доступен для partials. Scope может включать различные свойства – примитивы, объекты или методы. Все методы добавленные в scope, могут быть вызваны с помощью выражений AngularJS внутри partials, которые связанны с данным scope или прямым вызовом метода любым компонентом, у которого есть ссылка на scope. С помощью соответствующих директив, данные добавляются в scope, и могут быть связаны с представлением, таким образом, каждое изменение в свойстве scope будет отражено в представлении и каждое изменение в представлении будет отображено в scope.

    Еще одной важной характеристикой scope в любом AngularJS приложении является то, что они связаны через механизм наследования прототипа (за исключением изолированных scope). Таким образом любой дочерний scope может использовать методы его родителя, так как это свойства его прямого или косвенного прототипа.

    Наследование scope показано в следующем примере:

    С div#child связан scope ChildCtrl, но поскольку scope ChildCtrl является вложенным в BaseCtrl, то все методы из BaseCtrl доступны в ChildCtrl, при помощи наследования прототипа и поэтому метод foo будет доступен при нажатии на кнопку button#parent-method.

    Directives

    Директивы в AngularJS – это место где должны выполняться все манипуляции с DOM. Как правило если у вас в контроллере происходят манипуляции с DOM, то необходимо создать новую директиву или провести рефакторинг, который устранит манипуляции с DOM в контроллере. В простейшем случае у директивы есть имя и определение функции postLink, которая включает логику директивы. В более сложных случаях директива может содержать множество свойств, таких как:

    • template
    • compile function
    • link function
    • и т. д.

    Директивы можно использовать в partials, например:

    Filters

    Фильтры в AngularJS отвечают за инкапсуляцию логики, необходимой для форматирования данных. Обычно фильтры используются внутри partials, но так же через DI они доступны в контроллерах, директивах, сервисах или других фильтрах.
    Здесь простой пример фильтра, который преобразует строку в верхний регистр:

    Внутри partials фильтры могут быть использованы с помощью синтаксиса Unix конвейеров (Unix’s piping):

    Внутри контроллера фильтр может быть использован следующим образом:

    Services

    Любая часть логики, которая не относится к компонентам описанным выше, должна быть помещена в сервис. Обычно сервисы инкапсулируют специфическую область логики, неизменяемую логику, XHR, WebSockets и т. д. Когда контроллеры в приложении становятся слишком «толстыми», повторяющийся код должен быть вынесен в сервисы.

    Сервисы могут быть добавлены в любой компонент, который поддерживает DI (контроллеры, фильтры, директивы, другие сервисы):

    Паттерны AngularJS

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

    В последней главе мы рассмотрим некоторые архитектурные шаблоны, которые часто используются при разработке SPA (и не только) на AngularJS.

    Services

    Singleton

    Singleton (одиночка) — шаблон проектирования, который ограничивает создание экземпляра класса одним объектом. Это полезно когда необходимо координировать действия во всей системе. Концепция подходит для систем, которые функционируют более эффективно, когда существует только один объект или когда экземпляры ограничены некоторым количеством объектов.

    UML диаграмма иллюстрирует шаблон singleton:

    Когда какому любо компоненту требуется зависимость, AngularJS разрешает ее используя следующий алгоритм:

    • Берет имя зависимости и делает поиск в хеш-карте, которая определяется в лексическом замыкании. (поэтому она имеет приватную область видимости)
    • Если зависимость найдена AngularJS передает ее как параметр компонента
    • Если зависимость не найдена:
      • AngularJS создает ее при помощи вызова фабричного метода или его провайдера (т. е. $get). Обратите внимание, что создание зависимости может потребовать рекурсивный вызов по тому же алгоритму для определения всех зависимостей данной зависимости. Этот процесс может привести к циклической зависимости.
      • AngularJS кеширует ее внутри хеш-карты упомянутой выше.
      • AngularJS передает ее в качестве параметра компонента, для которого она указана.

    Лучше взгляните на исходный код AngularJS, который реализует getService:

    Представьте, что каждый service это singleton, потому что service создается только один раз. Кэш можно рассматривать, как менеджера singleton. Так же эта реализация немного отличается от той, что представлена в UML диаграмме, потому что вместо создания статической приватной ссылки на singleton внутри его конструктора, мы сохраняем ссылку внутри менеджера singleton.

    Таким образом, service это фактически singleton, но реализован не через шаблон singleton, тем самым обеспечивая некоторые преимущества по сравнению со стандартной реализацией:

    • улучшает тестируемость кода
    • можно управлять созданием объектов singleton (В данном случае IoC контейнер контролирует создание объектов используя ленивые вызовы.)


    Для более детального рассмотрения данной темы можете ознакомиться со статьей Misko Hevery’s в блоге Google Testing.

    Factory Method

    Factory Method (Фабричный метод так же известен как Виртуальный конструктор (англ. Virtual Constructor)) — порождающий шаблон проектирования, предоставляющий подклассам интерфейс для создания экземпляров некоторого класса. В момент создания наследники могут определить, какой класс создавать. Иными словами, Фабрика делегирует создание объектов наследникам родительского класса. Это позволяет использовать в коде программы не специфические классы, а манипулировать абстрактными объектами на более высоком уровне.

    Давайте рассмотрим следующий фрагмент:

    Здесь для определения нового «provider» используется функция обратного вызова config. «Provider» это объект с методом $get. Поскольку в JavaScript нет интерфейсов и язык использует «утиную» типизацию, то договорились фабричный метод в «provider» называть $get.

    Каждый service, filter, directive и controller имеют provider (т. е объект, который имеет фабричный метод $get), он отвечает за создание экземпляров компонента.

    Мы можем копнуть немного глубже в реализацию AngularJS:

    В примере вы можете видеть как в действительности используется метод $get:

    В фрагменте выше вызывается метод invoke и ему в качестве первого аргумента передается фабричным метод ($get) сервиса. Внутри метода invoke вызывается функция annotate, которой в качестве первого аргумента так же передается фабричный метод. Функция annotate разрешает все зависимости, через механизм DI AngularJS (рассматривался выше). После разрешения всех зависимостей, вызывается фабричный метод:

    Если рассуждать в терминах описанной выше UML диаграммы, то мы можем вызвать Creator, который через фабричный метод вызовет «ConcreteCreator» который создаст «Product».

    В данном случае мы получаем некоторые преимущества используя шаблон фабричный метод, потому что используется косвенное создание экземпляров. Таким образом фреймворк влияет на макеты/шаблоны создания новых компонентов, потому что:

    • это наиболее подходящий момент, когда нужно создать компонент
    • разрешить все зависимости компонента
    • управлять количеством разрешенных экземпляров компонента (для service и filter один, но много для controller)

    Decorator

    Decorator (Декоратор) — структурный шаблон проектирования, предназначенный для динамического добавления дополнительного поведения к объекту. Шаблон Декоратор предоставляет гибкую альтернативу создания подклассов с целью расширения функциональности.

    AngularJS из коробки предоставляет возможности для расширения и/или повышения функциональности уже существующих service’ ов. Используя метод decorator или $provide вы можете создать обертку для любого service, уже определенного вами или из сторонней библиотеки:

    Приведенный выше пример определяет новый service с именем «foo». В функции обратного вызова «config» вызывается метод $provide.decorator и ему в качестве первого аргумента передается имя service, который мы хотим декорировать, вторым аргументом передается функция, она собственно и реализует декоратор. $delegate хранит ссылку на оригинальный service foo. Мы декорируем service переопределяя его метод bar. Фактически декорирование просто расширение bar, путем включения еще одного состояния console.log — console.log(‘Decorated’) и после чего вызываем оригинальный метод bar в соответствующем контексте.

    Использование шаблона особенно полезно, когда нам нужно, изменить функциональность service созданных третьими лицами. В тех случаях, когда необходимы многочисленные декораторы (например, при измерении производительности методов, авторизации, регистрации и т.д.) может получиться много дублируемого кода и нарушение принципа DRY. В таких случаях целесообразно использовать аспектно-ориентированое программирование. АОП фреймворк для AngularJS можно найти на github.com/mgechev/angular-aop.

    Facade

    Шаблон Facade (фасад) — структурный шаблон проектирования, позволяющий скрыть сложность системы путем сведения всех возможных внешних вызовов к одному объекту, делегирующему их соответствующим объектам системы.
    Facade может:

    1. Сделать более легким использование библиотек, понимание и тестирование, так как facade имеет более подходящие методы для выполнения общих задач
    2. Сделать библиотеку более читабельной, по той же причине
    3. Уменьшить зависимость внутренних библиотек от внешнего кода, поскольку большая часть кода использует facade, это позволяет разрабатывать систему более гибко
    4. Обернуть плохо спроектированную коллекцию API-интерфейсов, одной хорошо спроектированной (в соответствии с потребностями задачи)

    В AngularJS есть несколько facade’ ов. Каждый раз когда вы хотите предоставить высокоуровневый API для некоторой функциональности, вы практически создаете фасад.

    К примеру, давайте посмотрим как мы можем создать XMLHttpRequest POST запрос:

    Если мы хотим отправить данные используя AngularJS $http сервис, мы можем:

    Второй вариант представляет предварительно настроенную версию, которая создает HTTP POST запрос.
    Третий вариант, это высокоуровневая абстракция созданная с помощью $resource service и построена поверх $http service. Мы еще раз рассмотрим этот service в разделах Active Record и Proxy.

    Proxy

    Proxy (Заместитель) — структурный шаблон проектирования, предоставляет объект, который контролирует доступ к другому объекту, перехватывая все вызовы (выполняет функцию контейнера). Proxy может взаимодействовать с чем угодно: сетевым соединением, большим объектом в памяти, файлом или другими ресурсами, которые дорого или невозможно копировать.

    Мы можем различать три типа прокси:

    • Virtual Proxy
    • Remote Proxy
    • Protection Proxy

    В этом подразделе мы рассмотрим реализованный в AngularJS Virtual Proxy.
    В фрагменте ниже, мы вызываем метод get объекта $resource с именем User:

    console.log выведет пустой объект. Так как AJAX запрос выполнится асинхронно после вызова User.get, и во время вызова console.log у нас не будет данных пользователя. Сразу после вызова User.get, выполняется GET запрос, он возвращает пустой объект и сохраняет ссылку на него. Мы можем представить себе этот объект как virtual proxy, он будет заполнен данными как только клиент получит ответ от сервера.

    Как это работает в AngularJS? Давайте рассмотрим следующий фрагмент:

    После выполнения фрагмента кода, показанного выше, свойство user объекта $scope будет пустым объектом (<>), это означает, что user.name будет undefined и не будет отображено. После того как сервер вернет ответ для GET запроса, AngularJS заполнит этот объект данными, полученными с сервера. В течении следующего $digest цикла, AngularJS обнаружит изменения в $scope.user и это приведет к обновлению представления.

    Active Record

    Active Record – это объект, который хранит данные и поведение. Обычно большинство данных в этом объекте постоянны, обязанность объекта Active Record заботиться о связи с базой данных для создания, обновления, поиска и удаления данных. Он может делегировать эту ответственность на объекты более низкого уровня, но вызов объекта Active Record или его статических методов, приведет к взаимодействию с БД.

    В AngularJS определен service $resource. В текущей версии AngularJS (1,2+) он распространяется отдельным модулем и не включен в ядро.
    В соответствии с документацией $resource:
    $resource — это фабрика для создания объектов $resource, которые позволяют взаимодействовать с RESTful источниками данных на стороне сервера. Объект $resource имеет методы, которые предоставляют высокоуровневое поведение, без необходимости взаимодействовать с низкоуровневым service’ ом $http.

    Здесь показано, как можно использовать $resource:

    Вызов $resource создает конструктор для экземпляров нашей модели. Каждый из экземпляров модели будет иметь методы, которые могут быть использованы для различных операций CRUD.

    Таким образом мы можем использовать функцию конструктор и его статические методы:

    Код выше будет сразу возвращать пустой объект и сохранять ссылку на него. После того, как будет получен и проанализирован ответ, AngularJS заполнит объект полученными данными (см. proxy).
    Вы можете найти более детальную документацию по «магии» объекта $resource и AngularJS.
    Так Мартин Фаулер утверждает что:
    Объект Active Record должен заботиться о связи с БД, для того что бы создавать…
    $resource не реализует полного шаблона Active Record, так как он взаимодействует с RESTful сервисом вместо БД. Во всяком случае мы можем рассматривать его как «Active Record для взаимодействия с RESTful».

    Intercepting Filters

    Создает цепочку фильтров для выполнения простых задач пред/пост обработки запросов.

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

    В AngularJS мы имеем представление о Intercepting Filters в $httpProvider. $httpProvider имеет свойство interceptors (перехватчики), оно включает список объектов. У каждого объекта есть свойства: request, response, requestError, responseError.

    requestError вызывается если в предыдущем перехватчике произошла ошибка или он был отклонен, соответственно responseError вызывается, когда предыдущий перехватчик ответа возбудил исключение.

    Ниже базовый пример, как вы можете добавить перехватчики используя литерал объекта:

    Directives

    Composite

    Шаблон composite (компоновщик) – структурный шаблон проектирования. Шаблон composite описывает, как группировать объекты, что бы к ним можно было обращаться, так же как к одному объекту. Цель composite составить объекты в древовидную структуру, для представления иерархии от частного к целому.

    Согласно «Банде четырех», MVC ни что иное как сочетание:

    • Strategy
    • Composite
    • Observer

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

    Давайте посмотрим на следующий пример:

    В этом примере создается директива, которая является компонентом пользовательского интерфейса. Созданный компонент (с именем “zippy”) имеет заголовок и содержание. При нажатии на его заголовок переключается видимость его содержимого.

    Из первого примера мы можем заметить, что дерево DOM это композиция элементов. Корневой компонент это html, сразу же за ним следуют вложенные элементы head, body и так далее…

    Во втором примере, мы видим, что свойство директивы template содержит разметку с директивой ng-transclude. Это означает, что внутри директивы “zippy” может быть еще одна директива ng-transclude т. е. композиция директив. Теоретически мы можем делать бесконечную вложенность компонентов пока не достигнем конечного узла.

    Interpreter

    Interpreter (интерпретатор) – поведенческий шаблон проектирования, указывает, как определять выражения в языке. Основная идея, классифицировать каждый символ (терминальный или не терминальный) в специализированном языке программирования. Синтаксическое дерево (пример шаблона композиция) выражений используется для анализа (интерпретирования) выражения.

    С помощью $parse, AngularJS предоставляет свою собственную реализацию интерпретатора DSL (Domain Specific Language). Использование DSL упрощает и изменяет JavaScript. Основная разница между AngularJS и JavaScript выражениях в том что AngularJS выражения:

    • могут включать фильтры с UNIX подобным синтаксисом
    • не возбуждают никаких исключений
    • не имеют никакого управления потоком состояния (исключения, циклы, условия так же могут использовать тернарный оператор)
    • выполняются в полученном контексте (контекст текущего $scope)

    Внутри $parse определены два основных компонента:

    При получении выражения, оно разбивается на лексемы и кэшируется (из-за проблем с производительностью).
    Терминальные выражения в AngularJS DSL определены следующим образом:

    Каждую функцию связанную с каждым терминальным символом, можно представить как реализацию интерфейса AbstractExpression (абстрактных выражений).
    Клиент интерпретирует полученное выражение в определенном контексте – определенного $scope.
    Несколько простых выражений AngularJS:

    Template View

    Преобразует данные в HTML путем встраивания маркеров в HTML страницу.

    Динамическое отображение страницы не такая простая задача. Это связано с большим количеством конкатенации строк, манипуляций и проблем. Наиболее простой способ построить динамическую страницу — это написать свою разметку и включить в нее несколько выражений, которые будут обработаны в определенном контексте, в результате весь шаблон будет преобразован в конечный формат. В нашем случае этим форматом будет HTML (или даже DOM). Это именно то что делают шаблонизаторы – они получают DSL, обрабатывают его в соответствующем контексте и затем преобразуют в конечный формат.

    Шаблоны очень часто используются на back-end. Например вы можете вставлять PHP код внутри HTML и создавать динамические страницы, так же вы можете использовать Smarty или eRuby в Ruby, чтобы вставлять Ruby код в статические страницы.

    В JavaScript есть много шаблонизаторов, таких как mustache.js, handlebars и т.д. Большинство из них работают с шаблоном как со строкой. Шаблон может храниться различными способами:

    • статический файл, который будет получен AJAX’ом
    • скрипт встроенный внутри вашего представления
    • строка внутри вашего JavaScript кода
    Топ-пост этого месяца:  Свойственные Vue js преимущества и недостатки оценка после перехода с React

    К примеру:

    Шаблонизатор превращает строку в элементы DOM, путем объединения ее с полученным контекстом. Таким образом все встроенные в разметку выражения анализируются и заменяются их значениями.

    Например, если мы обработаем шаблон показанный выше в контексте объекта: < names: ['foo', 'bar', 'baz'] >то получим:

    На самом деле шаблоны в AngularJS это обычный HTML. Они не находятся в промежуточном формате, как большинство шаблонов. Что делает AngularJS компилятор, что бы обойти дерево DOM и найти уже известные директивы (элементы, атрибуты, классы или даже комментарии)? Когда AngularJS находит любую из этих директив он вызывает логику связанную с ней, она может включать определение различных выражений в контексте текущего $scope.

    В контексте scope:

    Будет получен тот же результат что и выше. Главное отличие в том, что шаблон расположен не внутри тега script, здесь это просто HTML.

    Scope

    Observer

    Шаблон observer (наблюдатель) – поведенческий шаблон проектирования, в котором объект называемый субъектом, хранит список своих зависимостей, которые называются наблюдателями и уведомляет их при каких либо изменениях состояния, обычно вызовом одного из их методов. В основном используется для реализации распределенных систем обработки событий.

    В приложениях AngularJS есть два основных способа взаимодействия между scope.

    Первый, вызов методов родительского scope из дочернего scope. Это возможно, потому что дочерний scope наследует прототип своего родителя, как упоминалось выше (смотреть Scope). Это позволяет осуществлять одностороннее взаимодействие от ребенка к родителю. Иногда необходимо вызвать метод дочернего scope или уведомить его о возникновении события в родительском scope. AngularJS предоставляет встроенный шаблон наблюдатель, который позволяет делать это.

    Второй возможный вариант использования шаблона observer, когда несколько scope подписаны на события, но scope в котором оно возникает ничего о нем не знает. Это позволяет уменьшить связанность scope’ ов, они не должны ничего знать о других scope.

    Каждый scope в AngularJS имеет публичные методы $on, $emit и $broadcast. Метод $on в качестве аргументов принимает имя события и функцию обратного вызова. Эту функцию можно представить как наблюдателя – объект который реализует интерфейс observer (В JavaScript все функции первого класса, поэтому мы можем обеспечить только реализацию метода уведомления).

    Таким образом текущий scope подписывается на событие «event-name». Когда оно возникнет в любом из родительских или дочерних scope, будет вызван обработчик.


    Методы $emit и $broadcast используются для запуска событий, соответственно вверх и вниз по цепочке наследования. К примеру:

    В примере выше scope генерирует событие «event-name» вверх для всех scope. Это значит что каждый родительский scope, который подписан на событие «event-name», будет уведомлен и его обработчик будет вызван.

    Тоже самое происходит когда вызывается метод $broadcast. Разница лишь в том, что событие будет передаваться вниз – для всех дочерних scope. Каждый scope может подписаться на любое событие с несколькими функциями обратного вызова (т. е. он может связать несколько наблюдателей с данным событием).

    В JavaScript сообществе этот шаблон более известен как публикация/подписка.

    Chain of Responsibilities

    Chain of Responsibilities (цепочка обязанностей) – поведенческий шаблон проектирования, состоит из объекта команды и последовательности обрабатывающих объектов (обработчиков). Каждый обработчик содержит логику, определяющую тип команды, которую он может обработать. Затем команда поступают к следующему обработчику в цепочке. Шаблон так же содержит механизм для добавления новых обработчиков в конец этой цепочки.

    Как показано выше, scope образует иерархию, известную как цепочка scope. Некоторые из этих scope изолированы, это значит, что они не наследуют прототипы своих родительских scope, но связаны с ним через его свойство $parent.

    После вызова $emit или $broadcast возникает событие, которое начинает движение (вниз или вверх в зависимости от вызванного метода) по цепочке scope, ее можно представить как шину событий или точнее как цепочку обязанностей. Каждый последующий scope может:

    • Обработать событие и передать его следующему scope в цепочке
    • Обработать событие и остановить его распространение
    • Пропустить событие к следующему scope в цепочке, без его обработки
    • Остановить распространение события без его обработки

    В примере ниже, ChildCtrl генерирует событие, которое распространяется вверх по цепочке scope. Здесь каждый родительский scope (ParentCtrl и MainCtrl) должны обработать событие записав в консоль: «foo received». Если какой нибудь из scope должен быть конечным получателем, он может вызвать метод stopPropagation в объекте события.

    Обработчики в показанной выше UML диаграмме, являются различными scope, добавленными в контроллер.

    Command

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

    В AngularJS шаблон Command позволяет описать реализацию связывания данных (data binding).
    Когда мы хотим связать нашу модель с представлением мы можем использовать директиву ng-bind (для одностороннего связывания данных) и ng-model (для двустороннего связывания данных). К примеру, если мы хотим, что бы каждое изменение модели отображалось в представлении:

    Теперь каждый раз когда мы изменяем значение foo, текст внутри тега span тоже будет изменен. Также можно использовать более сложные выражения:

    В примере выше значением тега span будет сумма значений foo и bar в верхнем регистре. Что происходит внутри?
    В каждом scope есть метод $watch. Когда компилятор AngularJS находит директиву ng-bind, он создает нового наблюдателя для выражения foo + ‘ ‘ + bar | uppercase, ($scope.$watch(«foo + ‘ ‘ + bar | uppercase», function () < /* body */ >);). Функция обратного вызова будет вызвана каждый раз когда изменяется значение выражения. В данном случае функция обратного вызова будет обновлять значение тега span.

    Вот несколько первых строк реализации $watch:

    Мы можем представить watcher как Command. Выражение Command будет вычисляться в каждом цикле «$digest». Как только AngularJS обнаружит изменение выражения, он вызовет функцию слушателя. Watcher включает всю необходимую информацию для наблюдения и делегирования выполнение команды слушателю (фактическому получателю). Мы можем представить $scope как Client и цикл $digest как Invoker команд.

    Controllers

    Page Controller

    Объект, который обрабатывает запросы определенной страницы или действия на сайте. Мартин Фаулер.

    Согласно 4 контроллерами на страницу:
    Шаблон контроллер страницы допускает ввод данных с полученной страницы, выполнение запрошенных действий для модели и определяет правильное представление для результирующей страницы. Разделение диспетчерской логики от остального кода представления.

    Из-за большого количества дублируемого кода на страницах (к примеру футеры, хедеры, код заботящийся о сессии пользователя) контроллеры могут образовывать иерархию. В AngularJS есть контроллеры, которые ограничены scope. Они не принимают запросы пользователей, так как это ответственность $route или $state, а за отображение отвечают директивы ng-view/ui-view.

    Так же как в контроллерах страницы, контроллеры AngularJS отвечают за взаимодействие с пользователем, обеспечивая обновление моделей. Эти модели после добавления в scope не защищены от просмотра, все методы включенные в представление в итоге становятся действиями пользователя (методы scope). Другое сходство между контроллерами страниц и AngularJS контроллерами – это иерархия, которую они образуют. Этому соответствует иерархия scope видимости. Таким образом простыми действиями мы можем изолировать базовые контроллеры.

    Контроллеры AngularJS очень похожи на ASP.NET WebForms, так как их обязанности практически одинаковы. Вот пример иерархии между несколькими контроллерами:

    Этот пример иллюстрирует самый простой способ повторного использования логики с помощью базового контроллера, но в любом случае в «production» приложениях не рекомендуется помещать логику авторизации в контроллеры. Доступ к различным маршрутам можно определить на более высоком уровне абстракции.
    ChildCtr отвечает за отображение модели в представлении и обработку действий, таких как нажатие на кнопку с названием «Click».

    Others

    Module Pattern

    На самом деле это не шаблон проектирования от «банды четырех» и даже ни один из «Patterns of Enterprise Application Architecture». Это традиционный JavaScript шаблон проектирования, целью которого является обеспечение инкапсуляции.
    Используя шаблон модуль вы можете получить приватность данных на основе функционально-лексической области видимости. Каждый модуль может иметь ноль и более приватных методов, которые скрыты в локальной области видимости.

    Эта функция возвращает объект, который предоставляет публичный API для данного модуля:

    В примере выше IIFE (Immediately-Invoked Function Expression — выражение немедленно вызванной функции), которая после вызова возвращает объект, с двумя методами (setTitle и getTitle). Возвращенный объект присвоен переменной Page. В таком случае пользователь объекта Page не имеет прямого доступа к переменной title, которая определена внутри локальной области видимости IIFE.

    Шаблон модуль очень полезен при определении service в AngularJS. Используя этот шаблон мы можем достичь (и на самом деле достигаем) приватности:

    После того как мы добавим foo в любой другой компонент, у нас не будет возможности использовать приватные методы, только публичные. Это решение является довольно мощным, особенно, когда мы создаем библиотеки для повторного использования.

    Data Mapper

    Шаблон Data Mapper – это слой доступа к данным, который выполняет двунаправленную передачу данных между постоянным хранилищем данных (часто это реляционная БД) и данными в памяти. Цель этого шаблона – хранить в памяти представление постоянных данных, независимо друг от друга и от себя самого.

    Как уже говорилось Data Mapper используется для двунаправленной передачи данных между постоянным хранилищем данных и данными в памяти. Обычно AngularJS приложение взаимодействует с API сервера, которое написано на любом серверном языке (Ruby, PHP, Java, JavaScript и т.д.).

    Если у нас есть RESTful API, service $resource поможет нам взаимодействовать с сервером в Active Record подобном стиле. Хотя некоторые приложения возвращают данные с сервера не в самом подходящем формате, который мы хотим использовать на front-end.

    К примеру, давайте предположим у нас есть приложение в котором у каждого пользователя:

    • name
    • address
    • list of friends

    И наше API у которого есть следующие методы:

    • GET /user/:id – возвращает имя и адрес полученного пользователя
    • GET /friends/:id – возвращает список друзей данного пользователя

    Одно из решений, использовать два различных service, один для первого метода и другой для второго. Возможно более подходящим решением будет, использование одного service, который называется User, он загружает друзей пользователя, когда мы запрашиваем User:

    Таким образом мы создали псевдо Data Mapper, который адаптируется к нашему API в соответствии с требованиями SPA.
    Мы можем использовать User следующим образом:

    Технология AngularJS от Google

    AngularJS является JavaScript-фреймворком с открытым исходным кодом, разрабатываемым Google. Предназначен для разработки одностраничных приложений. Его цель — расширение браузерных приложений на основе MVC шаблона, а также упрощение тестирования и разработки.

    Фреймворк работает с HTML, содержащим дополнительные пользовательские атрибуты, которые описываются директивами, и связывает ввод или вывод области страницы с моделью, представляющей собой обычные переменные JavaScript. Значения этих переменных задаются вручную или извлекаются из статических или динамических JSON-данных.

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

    Цели разработки:


      Отделение DOM-манипуляции от логики приложения, что улучшает тестируемость кода. Отношение к тестированию как к важной части разработки. Сложность тестирования напрямую зависит от структурированности кода. Разделение клиентской и серверной стороны, что позволяет вести разработку параллельно. Проведение разработчика через весь путь создания приложения: от проектирования пользовательского интерфейса, через написание бизнес-логики, к тестированию.

    Angular придерживается MVC-шаблона проектирования и поощряет слабую связь между представлением, данными и логикой компонентов. Используя внедрение зависимости, Angular переносит на клиентскую сторону такие классические серверные службы, как видозависимые контроллеры. Следовательно, уменьшается нагрузка на сервер и веб-приложение становится легче.

    Популярные Angular-директивы

    С помощью директив AngularJS можно создавать пользовательские HTML-теги, чтобы добавить поведение некоторым элементам.

    • ng-app — Объявляет элемент корневым для приложения и может быть изменен с помощью пользовательских HTML-тегов.
    • ng-bind — Автоматически заменяет текст HTML-элемента на значение данного выражения.
    • ng-model — Как и ng-bind, но обеспечивает двустороннее связывание данных между представлением и областью видимости.
    • ng-class — Определяет классы для динамической загрузки.
    • ng-controller — Определяет JavaScript-контроллер для вычисления HTML-выражений.
    • ng-repeat — Создает экземпляр для каждого элемента из коллекции.
    • ng-show и ng-hide — Показывает или скрывает элемент в зависимости от значения логического выражения.
    • ng-switch — Создает экземпляр шаблона из множества вариантов, в зависимости от значения выражения.
    • ng-view — базовая директива, отвечает за обработку маршрутов, которые принимают JSON перед отображением шаблонов, управляемых указанными контроллерами.

    Двустороннее связывание данных

    Двустороннее связывание данных в AngularJS является наиболее примечательной особенностью и уменьшает количество кода, освобождая сервер от работы с шаблонами. Вместо этого, шаблоны отображаются как обычный HTML, наполненный данными, содержащимися в области видимости, определенной в модели. Сервис $scope в Angular следит за изменениями в модели и изменяет раздел HTML-выражения в представлении через контроллер. Кроме того, любые изменения в представлении отражаются в модели. Это позволяет обойти необходимость манипулирования DOM и облегчает инициализацию и прототипирование веб-приложений.

    Плагин для Chrome

    В июле 2012 года команда Angular выпустила плагин для браузера Google Chrome под названием Batarang, который облегчает отладку веб-приложений, построенных на Angular. Расширение позволяет легко обнаруживать узкие места и предлагает графический интерфейс для отладки приложений.

    История разработки

    AngularJS был первоначально разработан в 2009 году Мишко Хевери и Адамом Абронсом как программное обеспечение позади сервиса хранения JSON-данных, измеряющихся мегабайтами, для облегчения разработки приложений организациями. Сервис располагался на домене «GetAngular.com» и имел нескольких зарегистрированных пользователей, прежде чем они решили отказаться от идеи бизнеса и выпустить Angular как библиотеку с открытым исходным кодом.

    Абронс покинул проект, но Хевери, работающий в Google, продолжает развивать и поддерживать библиотеку с другими сотрудниками Google Игорем Минаром и Войта Джином.

    DOM-манипуляция в компоненте AngularJS 1.5

    Я попытался обернуть голову вокруг концепции компонента AngularJS, и я начал понимать принцип, но когда я попытался его практиковать, я нашел пример, когда не знаю, как реализовать это с компонентом.

    Мне нужно реализовать линейный прогресс, у него есть шаблон, поэтому логически должен быть компонент, а не директива, но я не могу найти способ делать манипуляции с DOM в компоненте, и кажется странным иметь директиву внутри такой маленький компонент. Вот основная реализация директивы:

    JS

    HTML

    CSS

    Итак, возможно, я понял принцип компонента неправильно, но я действительно много искал его и думал, что я понял принцип, прежде чем я столкнулся с этим примером.

    Итак, мой вопрос: могу ли я каким-либо образом манипулировать DOM в компоненте, и если ответ отрицательный, каков способ реализации этой директивы в компоненте (и он подходит вообще)? Я не считаю, что добавление директивы к компоненту только для изменения CSS — это подходящий выбор, поэтому я застрял.

    Создан 13 сен. 16 2020-09-13 18:09:03 kemsbe

    не понадобилось бы манипуляции с dom или ни одного из js в вашей ссылке, если бы вы использовали ‘ng-style’ – charlietfl 13 сен. 16 2020-09-13 18:20:47

    @charlietfl oops, похоже, что я действительно могу использовать ng-style и передавать значение там, теперь это выглядит очевидным , спасибо, я думаю, вы можете опубликовать его как ответ – kemsbe 13 сен. 16 2020-09-13 18:37:57

    Вам нужно сделать работу своей директивой или вам нужен новый компонентный подход? Проверенный ответ остается директивой и не отвечает на вопрос – Joaozito Polo 13 сен. 16 2020-09-13 19:19:19

    @JoaozitoPolo Мне нужен компонентный подход, но, как я понял, мне все равно нужно использовать внутренний компонент директивы, ng-style или custom, я прав? – kemsbe 13 сен. 16 2020-09-13 19:39:20

    3 ответа

    Чтобы устранить ваше замешательство о компоненте против директивы, чтобы использовать один над другим — это вопрос того, как вы разрабатываете свое приложение.

    Если вы предпочитаете использовать архитектуру MVC (MVVM, MVW, MV *), нет смысла иметь компоненты. Вы просто создаете представления, контролируемые контроллерами и директивами, которые будут изменять или управлять некоторыми элементами DOM.

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

    Начиная с 1.5, директива подходит очень близко к компонентам. Вы можете избавиться от области действия, создать контроллер . и т. Д., У вас есть только немного более шаблонный код для записи.

    Если вы хотите, чтобы ваше приложение следит за архитектурой (реагируйте, веб-компоненты, угловые2 . и т. Д.), Тогда все в приложении должно быть компонентом. (логин, навигация, нижний колонтитул . и т. д.), а компоненты могут иметь меньшие компоненты. (компонент загрузки файла может содержать компонент индикатора выполнения).

    Когда требуется больше элементов управления, то при использовании директив. Если для вас нет действующей угловой директивы (ngStyle, ngClass, ngShow . и т. Д.), Вы создаете свои. (Вы хотите вход, чтобы получить фокус автоматически, вы можете создать директиву)

    Чтобы ответить на этот прогресс бар вещь, это то, как я хотел бы написать свой компонент:

    PS: Стиль css был скопирован с css-tricks, чтобы сэкономить время.

    Создан 13 сен. 16 2020-09-13 19:58:35 gyc

    . Спасибо за такой полный ответ, так как теперь я понимаю, угловой 1.x не совсем разработан для архитектуры компонентов, это больше о архитектуре MV *, правильно ? А для архитектуры компонентов такие рамки, как реагирующие или угловые 2, более подходят, я прав? Итак, для углового 1.x лучше придерживаться директив и использовать компоненты только в том случае, если необходимо отделить часть приложения, верно? – kemsbe 13 сен. 16 2020-09-13 20:24:44

    @IlyaIlin no, от 1.5 и вы можете создавать приложения на основе 100% компонентов. Это зависит только от вас (или вашего босса). При работе каждое приложение, которое мы начинаем в этом году, будет основано на компонентах (angular2 не готов к выпуску). Наша интрасеть составляет 100% с угловыми 1,5 компонентами. Некоторые команды более старой школы, и мы придерживаемся MVC в некоторых других проектах. (ничто не шокирует это). Это вопрос мнения. Компоненты более современные (мода), но код действительно чище, чем у нас с MVC. – gyc 13 сен. 16 2020-09-13 20:32:55

    Большое вам спасибо, вы действительно сделали это более понятным для меня – kemsbe 13 сен. 16 2020-09-13 20:34:58

  • Добавить комментарий