AngularJS: Смена хеша без перезагрузки контроллера

AngularJs прекрасен и подходит для любых страниц, не только так любимых ныне SinglePageApplication, но для этого нужно правильно его готовить. Одно из правил готовки: позволь пользователю запоминать текущее состояние

Открытые окна, параметры поиска, номер страницы — все, что мне бы хотелось оставить у себя в закладках — это и есть «текущее состояние». Представьте ситуацию, когда пользователь долго и нудно искал на Вашем сайте нужную информацию. Наконец-то нашел и хочет ею поделиться. Как он это может сделать? Обычно лично я копирую ссылку и отправляю своим друзьям. Еще чаще — маме, которая и просила найти для нее что-то. И мама точно будет не рада, если получит ссылку, которая ведет на главную страницу сайта. Это и есть «передача текущего состояния».

Стандартный способ

Ссылка в шаблоне

И подхватывающий ее роутер с контроллером devItemsViewCtrl

Стандартный способ в одном контроллере все

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

Проблема, и ужасная проблема этого способа — мы начинаем каждый раз ПЕРЕРИСОВЫВАТЬ весь контроллер — посмотрите на вывод количества строк в логе — они будут на каждый клик! Это тормозит и это некрасиво как минимум.

Улучшенный способ в одном контроллере все

Так намного лучше с перерисовками, но мы теряем открытое состояние

Улучшенный способ + сохранение состояния в одном контроллере все

Казалось бы — вот оно! Сделали и сменили хеш — но тут мы натыкаемся на наш привязанный роутер!!! и о ужас — он таки подхватывает смену хеша и перебрасывает нас опять туда же!

Изменение хеша без редиректа

Для этого я применяю директиву location, и все уже мегаздорово! Хотя мы забыли сейчас одну мелочь — взять из текущего хеша — а вдруг уже есть страница

Финальный вариант

6 комментариев “AngularJS: Смена хеша без перезагрузки контроллера”

  1. Юрий

    Всё бы хорошо, но всё же URL лучше как минимум продублировать в атрибуте href у ссылки, что бы не терять такие важные стандартные возможности ссылок как:
    — Скопировать адрес ссылки не открывая её;
    — Открыть в другой вкладке;
    — Открыть в другом окне;
    — Использовать сочетания клавиш такие как Ctrl + MouseLeftClick, Shift + MouseLeftClick, MouseScrollClick и другие;
    — Посмотреть заранее по какому адресу будет переход;
    — Воспользоваться различными плагинами, расширениями браузеров и другим ПО для проверки ссылки, например антивирусной;
    — И многое другое.

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

    Ответить
    • гм, я конечно может что не поняла — но вот жеж он в первой же строке кода
      href="#/items/view{{item.id}}"

      Ответить
      • Смутило, что в одном из последних примеров так
        a href ng-click="showItem(item.id);">{{item.title}}</a
        Т. е. href уже пустой.
        Отсюда и мнение. А вообще за статью в любом случае спасибо! ))

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

          Ответить
      • Ну и второе, что смутило, это то, что нигде не производится проверка каким образом был произведён вызов клика на ссылке, а это значит, что часто зря будет произведено выполнение JS обработчика, иногда даже вместе, например, с открытием новой вкладки.

        Ответить
        • так тут как раз чтобы контроллер второй раз я старалась, а в новой вкладке все равно нужно отработать контроллеру (загрузка данных и тд), что и будет сделано — поиграйтесь… я сейчас со вторым ангулярчиком уже вожусь — он еще симпатичнее

          Ответить

Оставить комментарий

XHTML: Вы можете использовать такие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">