Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 06.10.2014, 11:25
Аватар для Sufir
Аспирант
Отправить личное сообщение для Sufir Посмотреть профиль Найти все сообщения от Sufir
 
Регистрация: 15.06.2008
Сообщений: 47

Двусторонняя связь location param и model
Мне нужно сделать своего рода тройной биндинг, т.е. изменение модели должно отражаться на адресной строке и наоборот, изменение параметра в строке должно менять модель. Что бы формировалась ссылка для текущего состояния фильтра, которой можно будет поделиться.

Я решил довольно костыльным методом:
$scope.$watch('selectedStaff', function () {
    var currentStaffId = ($scope.selectedStaff) ? $scope.selectedStaff.id : 0;

    if ($scope.selectedStaff !== undefined /*&& $scope.selectedStaff !== null*/) {
        $location.search('fStaffId', (currentStaffId) ? currentStaffId : null);
        /* Тут обновление данных... */
    }

});
$scope.$on('$routeUpdate', function () {

        var currentStaffId = parseInt($routeParams.fStaffId);
        if (currentStaffId > 0 && $scope.staffList.length > 0) {
            for (var k in $scope.staffList) {

                    if ($scope.staffList[k]['id'] === currentStaffId) {
                        $scope.selectedStaff = $scope.staffList[k];
                        break;
                    }

            }
        }

});


Но работает это довольно криво, то сбрасывается параметр в адресной строке (т.к. $watch сначала дважды вызывается со значениями null и undefined), приводит к лишним запросам к серверу, не обновляется селект... В общем, проблемный вариант.
Больше я пока ничего придумать не смог, опыта очень мало. Может подскажете как это правильно реализовать?

Последний раз редактировалось Sufir, 06.10.2014 в 11:32.
Ответить с цитированием
  #2 (permalink)  
Старый 09.10.2014, 23:52
Аватар для a.malitsky
Аспирант
Отправить личное сообщение для a.malitsky Посмотреть профиль Найти все сообщения от a.malitsky
 
Регистрация: 26.03.2010
Сообщений: 56

$location.search - я так же делаю. Еще сравниваю с default значениями чтобы все подряд в строку не пихать.

Чтобы watch не срабатывал изначально, поставь проверку newVal !== prevVal.

Я обновляю url сам, то есть не через watch, а когда что-то серьезно изменилось в состоянии app (в моем случае таких функций немного).

Про обращения на сервер и селект не понял.
Ответить с цитированием
  #3 (permalink)  
Старый 10.10.2014, 16:09
Аватар для Sufir
Аспирант
Отправить личное сообщение для Sufir Посмотреть профиль Найти все сообщения от Sufir
 
Регистрация: 15.06.2008
Сообщений: 47

Сообщение от a.malitsky Посмотреть сообщение
Чтобы watch не срабатывал изначально, поставь проверку newVal !== prevVal.

Я обновляю url сам, то есть не через watch, а когда что-то серьезно изменилось в состоянии app (в моем случае таких функций немного).
Примерно так и настроил, в общем-то работает, но как-то всё равно мне не очень нравится результат.

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

Сообщение от a.malitsky Посмотреть сообщение
Про обращения на сервер и селект не понял.
Ну, при изменении значения в селекте данные фильтруюутся, т.е. идёт запрос на сервер. Т.к. на данный момент 5 фильтров, то при открытии страницы 6 запросов серверу уходит. Ну, я сделал отложенную загрузку - первый раз гружу только когда все селекты уже готовы. Но из-за этого возникает другая проблема: пока ожидаем формирования всех селектов - старница пустая, получается долгая загрузка основных данных...

В общем кое-как я порешал и настроил, но как хорошо и правильно сделать пока не нашел.
Ответить с цитированием
  #4 (permalink)  
Старый 10.10.2014, 21:14
Аватар для a.malitsky
Аспирант
Отправить личное сообщение для a.malitsky Посмотреть профиль Найти все сообщения от a.malitsky
 
Регистрация: 26.03.2010
Сообщений: 56

При первой загрузке страницы фильтры можно же брать из строки или дефолтные, не вижу смысла ждать - шли один запрос сразу со всеми полученными (как значения) фильтрами. А ng-change на селектах пусть проверяет переменную вроде initialLoadIsActive.
Ответить с цитированием
  #5 (permalink)  
Старый 16.10.2014, 08:52
Аватар для MetaDriver
Аспирант
Отправить личное сообщение для MetaDriver Посмотреть профиль Найти все сообщения от MetaDriver
 
Регистрация: 24.04.2014
Сообщений: 66

Сообщение от Sufir Посмотреть сообщение
Мне нужно сделать своего рода тройной биндинг, т.е. изменение модели должно отражаться на адресной строке и наоборот, изменение параметра в строке должно менять модель.
...........

Но работает это довольно криво, то сбрасывается параметр в адресной строке (т.к. $watch сначала дважды вызывается со значениями null и undefined), приводит к лишним запросам к серверу, не обновляется селект... В общем, проблемный вариант.
Постановка задачи кривоватая - страдает ненужной избыточностью. Сделать, конечно можно и в такой постановке, но это довольно бессмысленно. Я бы поправил следующим образом:
  1. При начальной загрузке страницы значения фильтров брать из адресной строки, и как абсолютно верно заметил коллега a.malitsky - сразу же отправлять запрос на сервер.
  2. При редактировании селектов, изменения отображать в адресной строке односторонне. Обратный биндинг (адресная строка -> фильтры) в динамике (при уже открытой странице) совершенно избыточен и не нужен. Сложно представить умника, который будет редактировать строку поиска в гуглояндексе, редактируя адресную строку браузера (!! ), в то время как перед носом вполне человекоориентированный инпут (в твоём случае - селекты).
С этими поправками всё резко упрощается и ты, я уверен, с этим легко справишься.

Последний раз редактировалось MetaDriver, 16.10.2014 в 08:56.
Ответить с цитированием
  #6 (permalink)  
Старый 16.10.2014, 18:51
Аватар для a.malitsky
Аспирант
Отправить личное сообщение для a.malitsky Посмотреть профиль Найти все сообщения от a.malitsky
 
Регистрация: 26.03.2010
Сообщений: 56

Сообщение от MetaDriver
С этими поправками всё резко упрощается
Вроде там ничего сложного нет. А перезагрузка страницы (через f5) часто требует сохранения app state. И для этого обойтись без изменения параметров с их последующим чтением не получится.
Ответить с цитированием
  #7 (permalink)  
Старый 16.10.2014, 23:10
Аватар для MetaDriver
Аспирант
Отправить личное сообщение для MetaDriver Посмотреть профиль Найти все сообщения от MetaDriver
 
Регистрация: 24.04.2014
Сообщений: 66

Сообщение от a.malitsky Посмотреть сообщение
Вроде там ничего сложного нет. А перезагрузка страницы (через f5) часто требует сохранения app state. И для этого обойтись без изменения параметров с их последующим чтением не получится.
как эта логика соотносится с необходимостью заполнять селекты из содержимого адресной строки динамически (во время ручного редактирования адресной строки) ?
и причём здесь f5? перезагрузка страницы (f5, ctrl-f5) эквивалентна начальной загрузке по содержимому адресной строки. вам нужно отображать в адресную строку изменения ваших селектов, никто не спорит с этим.
а вот зачем обратный биндинг?

я не говорю, что вам не нужно парсить адресную строку, я сказал только что это достаточно сделать однократно, при начальной загрузке (инициализации) страницы. динамически отслеживать нет никакой необходимости. ну это, конечно, если ваше начальство не считает иначе.....
Ответить с цитированием
  #8 (permalink)  
Старый 21.10.2014, 05:37
Аватар для a.malitsky
Аспирант
Отправить личное сообщение для a.malitsky Посмотреть профиль Найти все сообщения от a.malitsky
 
Регистрация: 26.03.2010
Сообщений: 56

если просто что-то ввести, то ничего не произойдет, если нажать enter, то отработает router если я не путаю и получится изначальная загрузка app из параметров адресной строки.

Проверять что там изменил пользователь в адресной строке без перезагрузки (enter) state конечно не стоит. Согласен.

Последний раз редактировалось a.malitsky, 21.10.2014 в 05:42.
Ответить с цитированием
  #9 (permalink)  
Старый 21.10.2014, 17:30
Аватар для MetaDriver
Аспирант
Отправить личное сообщение для MetaDriver Посмотреть профиль Найти все сообщения от MetaDriver
 
Регистрация: 24.04.2014
Сообщений: 66

Ну и ладушки.
Ответить с цитированием
  #10 (permalink)  
Старый 29.10.2014, 15:34
Аватар для Sufir
Аспирант
Отправить личное сообщение для Sufir Посмотреть профиль Найти все сообщения от Sufir
 
Регистрация: 15.06.2008
Сообщений: 47

Сообщение от MetaDriver Посмотреть сообщение
При начальной загрузке страницы значения фильтров брать из адресной строки, и как абсолютно верно заметил коллега a.malitsky - сразу же отправлять запрос на сервер.
Просто "ожидание" гарантирует правильные значения в фильтрах. Если есть, к примеру, для какого-то параметра заданный список значений. У пользователя может быть какая-то битая ссылка или старая из закладок или присланная другим пользователем. Да и вообще всё что угодно в строке оказаться может (или не оказаться).
Соответственно в любом случае по готовности фильтров данные нужно обновить. Хотя бы в случае обнаружения такового несоответствия.

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



Опции темы Искать в теме
Искать в теме:

Расширенный поиск