06.10.2014, 11:25
|
|
Аспирант
|
|
Регистрация: 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.
|
|
09.10.2014, 23:52
|
|
Аспирант
|
|
Регистрация: 26.03.2010
Сообщений: 56
|
|
$location.search - я так же делаю. Еще сравниваю с default значениями чтобы все подряд в строку не пихать.
Чтобы watch не срабатывал изначально, поставь проверку newVal !== prevVal.
Я обновляю url сам, то есть не через watch, а когда что-то серьезно изменилось в состоянии app (в моем случае таких функций немного).
Про обращения на сервер и селект не понял.
|
|
10.10.2014, 16:09
|
|
Аспирант
|
|
Регистрация: 15.06.2008
Сообщений: 47
|
|
Сообщение от a.malitsky
|
Чтобы watch не срабатывал изначально, поставь проверку newVal !== prevVal.
Я обновляю url сам, то есть не через watch, а когда что-то серьезно изменилось в состоянии app (в моем случае таких функций немного).
|
Примерно так и настроил, в общем-то работает, но как-то всё равно мне не очень нравится результат.
У меня список объектов на странице, и целый ряд всевозможных фильтров для него, при изменении значений которых должен и список меняться, соответсвенно.
Сообщение от a.malitsky
|
Про обращения на сервер и селект не понял.
|
Ну, при изменении значения в селекте данные фильтруюутся, т.е. идёт запрос на сервер. Т.к. на данный момент 5 фильтров, то при открытии страницы 6 запросов серверу уходит. Ну, я сделал отложенную загрузку - первый раз гружу только когда все селекты уже готовы. Но из-за этого возникает другая проблема: пока ожидаем формирования всех селектов - старница пустая, получается долгая загрузка основных данных...
В общем кое-как я порешал и настроил, но как хорошо и правильно сделать пока не нашел.
|
|
10.10.2014, 21:14
|
|
Аспирант
|
|
Регистрация: 26.03.2010
Сообщений: 56
|
|
При первой загрузке страницы фильтры можно же брать из строки или дефолтные, не вижу смысла ждать - шли один запрос сразу со всеми полученными (как значения) фильтрами. А ng-change на селектах пусть проверяет переменную вроде initialLoadIsActive.
|
|
16.10.2014, 08:52
|
|
Аспирант
|
|
Регистрация: 24.04.2014
Сообщений: 66
|
|
Сообщение от Sufir
|
Мне нужно сделать своего рода тройной биндинг, т.е. изменение модели должно отражаться на адресной строке и наоборот, изменение параметра в строке должно менять модель.
...........
Но работает это довольно криво, то сбрасывается параметр в адресной строке (т.к. $watch сначала дважды вызывается со значениями null и undefined), приводит к лишним запросам к серверу, не обновляется селект... В общем, проблемный вариант.
|
Постановка задачи кривоватая - страдает ненужной избыточностью. Сделать, конечно можно и в такой постановке, но это довольно бессмысленно. Я бы поправил следующим образом: - При начальной загрузке страницы значения фильтров брать из адресной строки, и как абсолютно верно заметил коллега a.malitsky - сразу же отправлять запрос на сервер.
- При редактировании селектов, изменения отображать в адресной строке односторонне. Обратный биндинг (адресная строка -> фильтры) в динамике (при уже открытой странице) совершенно избыточен и не нужен. Сложно представить умника, который будет редактировать строку поиска в гуглояндексе, редактируя адресную строку браузера (!! ), в то время как перед носом вполне человекоориентированный инпут (в твоём случае - селекты).
С этими поправками всё резко упрощается и ты, я уверен, с этим легко справишься.
Последний раз редактировалось MetaDriver, 16.10.2014 в 08:56.
|
|
16.10.2014, 18:51
|
|
Аспирант
|
|
Регистрация: 26.03.2010
Сообщений: 56
|
|
Сообщение от MetaDriver
|
С этими поправками всё резко упрощается
|
Вроде там ничего сложного нет. А перезагрузка страницы (через f5) часто требует сохранения app state. И для этого обойтись без изменения параметров с их последующим чтением не получится.
|
|
16.10.2014, 23:10
|
|
Аспирант
|
|
Регистрация: 24.04.2014
Сообщений: 66
|
|
Сообщение от a.malitsky
|
Вроде там ничего сложного нет. А перезагрузка страницы (через f5) часто требует сохранения app state. И для этого обойтись без изменения параметров с их последующим чтением не получится.
|
как эта логика соотносится с необходимостью заполнять селекты из содержимого адресной строки динамически (во время ручного редактирования адресной строки) ?
и причём здесь f5? перезагрузка страницы (f5, ctrl-f5) эквивалентна начальной загрузке по содержимому адресной строки. вам нужно отображать в адресную строку изменения ваших селектов, никто не спорит с этим.
а вот зачем обратный биндинг?
я не говорю, что вам не нужно парсить адресную строку, я сказал только что это достаточно сделать однократно, при начальной загрузке (инициализации) страницы. динамически отслеживать нет никакой необходимости. ну это, конечно, если ваше начальство не считает иначе.....
|
|
21.10.2014, 05:37
|
|
Аспирант
|
|
Регистрация: 26.03.2010
Сообщений: 56
|
|
если просто что-то ввести, то ничего не произойдет, если нажать enter, то отработает router если я не путаю и получится изначальная загрузка app из параметров адресной строки.
Проверять что там изменил пользователь в адресной строке без перезагрузки (enter) state конечно не стоит. Согласен.
Последний раз редактировалось a.malitsky, 21.10.2014 в 05:42.
|
|
21.10.2014, 17:30
|
|
Аспирант
|
|
Регистрация: 24.04.2014
Сообщений: 66
|
|
Ну и ладушки.
|
|
29.10.2014, 15:34
|
|
Аспирант
|
|
Регистрация: 15.06.2008
Сообщений: 47
|
|
Сообщение от MetaDriver
|
При начальной загрузке страницы значения фильтров брать из адресной строки, и как абсолютно верно заметил коллега a.malitsky - сразу же отправлять запрос на сервер.
|
Просто "ожидание" гарантирует правильные значения в фильтрах. Если есть, к примеру, для какого-то параметра заданный список значений. У пользователя может быть какая-то битая ссылка или старая из закладок или присланная другим пользователем. Да и вообще всё что угодно в строке оказаться может (или не оказаться).
Соответственно в любом случае по готовности фильтров данные нужно обновить. Хотя бы в случае обнаружения такового несоответствия.
Сообщение от MetaDriver
|
Обратный биндинг (адресная строка -> фильтры) в динамике (при уже открытой странице) совершенно избыточен и не нужен.
|
Пожалуй что так. Перепишу в день рефакторинга.
|
|
|
|