ASP.NET MVC: Делаем голосование на сайте при помощи Knockout

Рис.1 “Опрос на сайте (пользователь еще не голосовал)”
И второй вариант отображения формы, это когда пользователь уже проголосовал.

Рис.2 “Опрос на сайте (пользователь уже голосовал)”
Звучит и выглядит просто, и поэтому я стороной обойду загрузку данных с сервера, запись данных на сервер, чтение настроек и проверку cookies, чтобы по возможности максимально рассказать о Knockout. Итак, если учесть, что все приготовления выполнены, то можно сразу приступить к программированию.
Входные данные
В папке Scripts/App создаю новый файл site.vm.polls.js. Теперь первым делом определю формат данных для объекта (Poll) (листинг 1):
1: var pollData = {
2: "question": "За двумя зайцами погонишься...",
3: "answers": [
4: { votes: 11, name: "ни одного не поймаешь." },
5: { votes: 5, name: "больше двух не поймаешь." },
6: { votes: 15, name: "ни одного волка не поймаешь." },
7: { votes: 9, name: "порвешься на две части." },
8: { votes: 39, name: "зачем бегать, лучше на авто!" }
9: ],
10: "selectedAnswer": null};
Это, так сказать, входные данные. В моем случае, они “жестко” прописаны в коде. Вы же можете сделать получение данных для опроса с сервера, через Web API, или с сервиса WCF. Немного комментариев относительно представленного кода.
- Строка 2: Сам вопрос.
- Строка 3-8: Это предложенные варианты ответа на поставленный вопрос.
- Строка 10: Ответ, который возможно уже дал пользователь, посещая сайт. Вы можете хранить его в базе данных или даже в cookies. Сейчас он у меня null, поэтому форма должна отобразить список ответов и вопрос. А если поле было заполнено (выбранный ответ), то форма должна отобразить результаты голосования.
Класс Answer (Ответ)
В предыдущем листинге (листинг 1) в строка 3 эти самые ответы на вопрос. “Завернем” класс в JavaScript (листинг 2):
1: site.vm.Answer = function (value, total) {
2: var isSelected = ko.observable(false),
3: votes = ko.observable(total),
4: name = ko.observable(value);
5: return {
6: isSelected: isSelected,
7: name: name,
8: votes: votes
9: };
10: },
Всё просто, единственное, что хотелось быть отметить, что свойство isSelected будет указыват на то выбран ли ответ в списке вариантов или нет.
Класс Poll (Опрос)
Этот класс и будет представляет “входные данные” (см. листинг 1). Самый большой класс в моем решении (листинг 3).
1: site.vm.Poll = function (data) {
2: var selectedItem = ko.observable(new site.vm.Answer()),
3: question = ko.observable(data.question),
4: answers = ko.observableArray([]),
5: answer = ko.observable(),
6: maxVotes = ko.observable(),
7: init = function () {
8: var max = 0;
9: var i;
10: for (i in data.answers) {
11: var cur = data.answers[i].votes;
12: if (cur && cur>max) {
13: max = cur;
14: }
15: }
16: max = Math.round(max * 1.1);
17: maxVotes(max);
18: for (i in data.answers) {
19: answers.push(new site.vm.Answer(data.answers[i].name, data.answers[i].votes));
20: }
21: if (data.selectedAnswer) {
22: answer(data.selectedAnswer);
23: }
24: },
25: setSelected = function (item) {
26: if (!item.isSelected()) {
27: selectedItem(item.name());
28: ko.utils.arrayForEach(answers(), function (i) {
29: if (i.isSelected && i.isSelected()) { i.isSelected(false); }
30: });
31: item.isSelected(true);
32: }
33: };
34:
35: init();
36:
37: return {
38: max: maxVotes,
39: selectedItem: selectedItem,
40: question: question,
41: answers: answers,
42: answer: answer,
43: setSelected: setSelected
44: };
45: };
И опять немного комментариев:
- Строка 2: Представляет выбранный пользователем ответ.
- Строка 6: Вообще-то, это свойство (maxVotes) я ввел только для того, чтобы правильно работал jQuery UI Progressbar, при помощи которого я планирую отображать результаты.
- Строка 7: Инициализация класса на основании входных данных. Запуск инициализации происходит в строке 35.
ViewModel для формы
На форме может быть много опросов, в моем варианте он один. Создаем ViewModel для формы Index.cshtml. Вот так выглядит pollViewModel (листинг 4):
1: site.vm.pollViewModel = function () {
2: var message = ko.observable("Выберите ваш вариант ответа на вопрос."),
3: poll = site.vm.Poll(pollData),
4: save = function () {
5: poll.answer(poll.selectedItem());
6: };
7:
8: return {
9: save: save,
10: poll: poll,
11: message: message
12: };
13: }();
Строка 2: Сообщение для пользователя. Мне не пригодилось, но можно использовать для вывода ошибок при работе сервиса.
Строка 3: Создаем экземпляр класса голосования (см. листинг 3).
Строка 4: Функция сохранения результатов голосования. В моем решении это просто обновления свойства answer. Но вы можете отправить результат на сервер или сохранить в cookies.
Магия Knockout – applyBindings
Голосование (Poll) я планирую показать на главной странице (то есть в котроллере Home, метод – Index). Я открыл представление (index.cshtml) и полностью его отчистил, и добавил туда такую разметку:
1: <divdata-bind="ifnot: poll.answer">
2: <h2data-bind="text: poll.question">h2>
3: <h4data-bind="text: message">h4>
4: <divdata-bind="foreach: poll.answers">
5: <divdata-bind="click: $parent.poll.setSelected"class="big">
6: <inputtype="radio"value="true" data-bind="checked: isSelected().toString()"class="poll"/>
7: <spandata-bind="text: name, css: {'selected': isSelected}">span>
8: div>
9: div>
10: <p>
11: <buttondata-bind="click: save">голосоватьbutton>
12: p>
13: div>
14: <divdata-bind="if: poll.answer">
15: <h2data-bind="text: poll.question() ' ' poll.answer()">h2>
16: <divdata-bind="foreach: poll.answers">
17: <spandata-bind="text: name">span>
18: <divdata-bind="progressbar: {value: votes(), max: $parent.poll.max()}">div>
19: <br/>
20: div>
21: div>
Всё на форме просто и, надеюсь, понятно. Единственное, что хотелось бы отметить, для отображения результатов в шаблоне (строка 18) используется bindingHandler, который я назвал “progressbar”. Когда вы установите nuget-пакет JsJite, у вас в папке scripts/app появится файл site.bindingHandlers.js, в котором уже много полезных “штучек”.
Заключение
В качестве заключения хочу предложить создать демо-проект и поэкспериментировать.
Подробнее: http://feedproxy.google.com/~r/blogmusor/~3/ReoYRvxCyJU/106
|
В качестве вступления Я буду строить решение на базе проекта, который был опубликован в предыдущей статье “ASP.NET MVC: И снова про форму обратной связи или куда еще втыкнуть Knockout”. Хочу чтобы |
ASP.NET MVC: Делаем голосование на сайте при помощи Knockout |
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2025-12-02 » Когда ошибка молчит: как бессмысленные сообщения ломают пользовательский опыт
- 2025-12-02 » 9 лучших бесплатных фотостоков
- 2025-12-02 » UTM-метки: ключевой инструмент аналитики для маркетолога
- 2025-12-02 » ПромоСтраницы Яндекса: Что такое и для чего служит
- 2025-12-02 » Метатеги для сайта: исчерпывающее руководство по Title, Description, Canonical, Robots и другим тегам
- 2025-11-26 » Оценка эффективности контента: превращаем информационный балласт в рабочий актив
- 2025-11-26 » 10 причин высокого показателя отказов на сайте
- 2025-11-26 » Когда и зачем обновлять структуру сайта
- 2025-11-26 » Скрытые демотиваторы: как мелочи разрушают эффективность команды
- 2025-11-26 » Зачем запускать MVP и как сделать это грамотно?
- 2025-11-20 » Половина российских компаний сократит расходы на транспорт и маркетинг в 2026 году
- 2025-11-20 » Перенос сайта с большим количеством ссылок
- 2025-11-20 » Перелинковка сайта: Что такое и как ее использовать
- 2025-11-20 » Критерии выбора SEO-специалиста и подрядчика для продвижения сайта
- 2025-11-20 » Применение искусственного интеллекта в рекламных агентствах: комплексное исследование трендов 2025 года
- 2025-11-19 » Геозапросы по-новому: как покорить локальное SEO с помощью ИИ
- 2025-11-14 » Консалтинг: сущность и ключевые направления
- 2025-11-14 » Онлайн-формы: универсальный инструмент для сбора обратной связи
- 2025-11-14 » Факторы конверсии органического трафика
- 2025-11-14 » Планирование рекламного бюджета: самостоятельный подход
- 2025-11-14 » Авторизация на сайте: как выбрать решение для удержания клиентов и сохранения продаж
- 2025-11-13 » Эффективные методы стимулирования клиентов к оставлению положительных отзывов
- 2025-11-13 » Налоговая реформа — 2026: грядущие изменения для предпринимателей
- 2025-11-13 » Альтернативы мессенджерам: что выбрать вместо Telegram и WhatsApp
- 2025-11-13 » Маркировка рекламы для начинающих: полное руководство по требованиям ЕРИР
- 2025-11-13 » ИИ не отберет вашу работу — её займет специалист, владеющий искусственным интеллектом
- 2025-10-29 » Как оценить эффективность работы SEO-специалиста: практическое руководство для маркетологов и владельцев бизнеса
- 2025-10-29 » Киберспорт как маркетинговый инструмент: стратегии привлечения геймеров
- 2025-10-29 » Как говорить с аудиторией о сложном
- 2025-10-29 » Что такое доказательства с нулевым разглашением (ZKP) и их роль в блокчейне
Мудрость приносит следующие три плода: дар хорошо мыслить, хорошо говорить и хорошо поступать Демокрит - (около 460 до н.э.- около 360 до н.э.) - древнегреческий философ |

Мы создаем практически любые сайты от продающих страниц до сложных, высоконагруженных и нестандартных веб приложений! Наши сайты это надежные маркетинговые инструменты для успеха Вашего бизнеса и увеличения вашей прибыли! Мы делаем красивые и максимально эффектные сайты по доступным ценам уже много лет!
Комплексный подход это не просто продвижение сайта, это целый комплекс мероприятий, который определяется целями и задачами поставленными перед сайтом и организацией, которая за этим стоит. Время однобоких методов в продвижении сайтов уже прошло, конкуренция слишком высока, чтобы была возможность расслабиться и получать \ удерживать клиентов из Интернета, просто сделав сайт и не занимаясь им...
Мы оказываем полный комплекс услуг по сопровождению сайта: информационному и техническому обслуживанию и развитию Интернет сайтов.
Контекстная реклама - это эффективный инструмент в интернет маркетинге, целью которого является увеличение продаж. Главный плюс контекстной рекламы заключается в том, что она работает избирательно.