Pull to refresh

Comments 18

Странно, что проблема различных дивайсов решается на стороне сервера, а не клиента, как это принято делать, например, при помощи CSS media queries.
очевидна проблема: слабое устройство может не суметь (в силу технических причин) обработать (да еще и верно) CSS «трюки».

Вы в реальных проектах пробовали это использовать? Я пробовал. Результат резко негативный. Мой «слегка устаревший» телефон не мог прожевать нормально «большой и сложный сайт» — тормозил, показывал некорретно, вылетал из браузера...
> Основное неудобство именно в том, что все View, которые вы делаете для страницы обрабатываются
> одним и тем же методом контроллера.

А можно реальный случай, когда для разных устройств нужные принципиально разные Controllers?

В остальном, статья от кэпа. Можно было не мутить кучу воды и после небольшого вступления перейти к IsNotChromeConstraint и по тексту.
Да, приведу пример на странице показывающей пользователю ассортимент товара — обычный browse list с картинками товаров.

Оптимальным подходом будет следующее:

Для XBOX мы показываем товар как обычно, ширина фиксирована, пейджинг нам не нужен — пользователь пролистывает страницу вниз и мы всевремя подгружаем вниз товар для показа (infinite scrolling). Страница может содержать виджеты социальных сетей, кнопки рейтинга товара и тому подобное.

Для SmartTV — ширина та же, но необходимо избавится от скроллинга, товар показывается постранично, все умещается на страницу без скроллинга, слева и справа страницы кнопки Влево/Вправо, в JavaScript обрабатываем key press events с кнопок пульта и делаем пост-беки для пейджинга. Никаких виджетов.

То есть и сама страница, ее функционал и внешний вид, а также server side для педжинга будут различными.
И какие там различия? Вы не номер страницы передавайте, а количество «сколько надо данных в штуках», «с какого id» и «с какой сортировкой и фильтрами». Магия и чуток умения — и никаких отличий.

К слову все компоненты (типа DevExpress) умеют такое — в asp.net там пейнджинг ИЛИ виртуальный режим без каких-то изменений данных для них в гридах.
Я бы сказал что различие в том, что
— для infinite scrolling у нас есть action method который принимает параметры и отдает JSON
— а для постраничного пейджинга у нас есть action method который отдает aspx/cshtml View, причем размер страницы в элементах фиксированный и не должен передаваться через параметры — у пытливого пользователя не должно быть возможности этим управлять.

Передавать параметр в метод управляя тем в каком формате отдавать результат или опираться на content-type запроса в данном случае не верно.

У Вас может использоватся одна и таже логика пейджинга, но методы контроллера — это presentation layer. Они будут разными и это правильно. Здесь не нужно стремиться делать универсальные механизмы.
Что-то вы все в кучу смешали. Json метод вообще в стороне тут (не влияет на код контроллера).

Смотрите: контроллер выдает одну страницу (первую). Далее представление для Xbox показывает страницу + организует скроллинг через JS. А ТВ версия опять лезет к контроллеру за новой страницей.
Я проиллюстрирую то, что предложил:

для Smart TV потребуется один метод:
— /catalog/{pageId} — возвращает html page

для Xbox/IE потребуется два метода:
— /api/catalog/{parameters set} — возвращает json для infinite scrolling
— /catalog — возвращает html page, нет input параметров

Вы предлагаете для обоих случаев пользоваться одним методом — - /catalog/{pageId}

Это возможно, но не правильно. Объясню почему.

Вы отдаете приложение на QA, они на xbox IE набирают /catalog/2 и выписывают дефект примерно следующего содержания: «как бы дитя не скролилло, любимых медведей не увидело». У Вас два пути решения проблемы:
— сделать для xbox метод без параметра
— сделать в контроллере условную логику основанную на том какой девайс/браузер используется, что является не верным решением. Именно от этого и следует уходить любыми средствами. Аналогичная условная логика во View также не желательна — поэтому MS и сделали View Modes в MVC 4.
> — /catalog — возвращает html page, нет input параметров

default values не? Тогда /catalog эквивалент /catalog/1

> они на xbox IE набирают /catalog/2

с какой это радости они не увидят результат? они получат вид «страница 2». А затем уже задача JS обеспечить скролинг в обе стороны.
infinite scrolling на JavaScript в обе стороны — интересная тема для блога, не хотите написать топик?
Не в обе стороны. Вверх он будет вполне конечный.
Вы не умеете делать asp.net mvc контролы, это я уже понял. Может будете удивлены, но контролы могут отдать и json.
Поясняю для тех кто незнаком:
1) вы пишете в контроллере нечто вроде
ActionResult Index() { var model = GetModel(GridQueryParams.Default); return View(model); } ActionResut MyGridPartial(GridQueryParams p) { var model = GetModel(p); return PartialView(model); }
2) в коде контрола пишете нечто вроде
@if(MyGridHelper.IsCallback){ Html.Raw(Model.ToJson()); //верните модель в callback-е как json } else{ <!-- это собственно контрол таблица, тут же ссылки вперед-назад, которые обрабатываются javascript-том (вызывая Partial метод, принимая данные, и делая с ними ЧТО угодно, включая "перезаполнение" таблицы). --> <table> blablabla </table> }
т.е. при калбэке верните json, иначе (по дефолту) html.
3) оборачиваете это всё в класс. Делаете экстеншен для HtmlHelper (так типа принято).
4) по вкусу: влияете на генерированный код контрола передавая ему параметры, например route values — что вызвать на callback. Также по вкусу выставляете (чем угодно — хоть пост фильтром) у каллбэк значения content-type и т.д.

NOTE: для того чтобы понять что к вам пришел callback вам надо передать нечто (значение) в самом запросе любым методом и обработать это нечто в MyGridHelper.get_IsCallback().

UPD: соответсвенно вам просто надо два контрола нарисовать — под «ajax» (как я написал выше) и «не под ajax».
Согласен с jonie. Больше подходит для попытки прикрутить к обычному сайту костыль для SmartTV.
Это спор аналогичный тому стоит ли пытаться на HTML 5 делать одно приложение работающее и на iOS, и на Android, и на Windows Phone 8. Ответ на него очень простой — если Вам нужен WoW результат и ресурсы позволяют, то нужно делать для каждой платформы нативное приложение.

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

В то же время открывать большенство сайтов на мобильных устройствах, телевизорах и приставках практически бесполезно, т.к. меню разворачивается на mouse over, комбобоксы закрываются до того как вы проскроллите до нужного пункта и автоматически уходит пост-бек, чтобы добраться до кнопки ОК нужно 25 раз нажать на кнопку Вниз, а на link button никак не попасть с джойстика. И все эти сайты не парятся по этому поводу :)

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

В условиях конкуренции выигрывает тот, кто к лесу задом, а к пользователю передом.
И где спор? Выше я говорил, что ваш пример — явный костыль. Т.е. изначально надо рассчитывать на поддержку разных платформ. И как раз «один сайт на HTML5» к моим словам не при чем.
Для реализации IsNotChromeConstraint лучше было бы использовать существующий IsChromeConstraint и отрицание. Добавить конструктор:
public IsNotChromeConstraint(IsChromeConstraint chromeConstraint)
{
_chromeConstraint = chromeConstraint;
}

а в вызове метода Match класса IsNotChromeConstraint возвращать:
return !_chromeConstraint.Match(...);
Верно :) еще лучше сделать Constraint, который принимает делегат с условием — аналогично тому как задаются DisplayMode в DisplayModeProvider-e.
Если уж так необходимы разные контроллеры или экшены для разных клиентов, не проще ли сделать свою реализацию ActionInvoker, который будет ориентироваться, например, на некий атрибут в котором указывать для DisplayMode этот экшен?
Only those users with full accounts are able to leave comments. Log in, please.