Как я могу реализовать части представлений, которые зависят от свойств модели?
У меня есть функциональные требования, такие как этот пример:
- "Гражданство" состоит из 3 переключателей, а именно: "Гражданин Южной Африки", "Не южноафриканец, с разрешением на работу" и "Не южноафриканец, без разрешения на работу".
- "Номер разрешения на работу" представляет собой текстовое поле, ограниченное 15 символами, и активируется в случае "не Южно-Африканской,
с разрешением на работу "в поле" Гражданин "
Я хотел бы создать некий универсальный контейнер для полевых редакторов, например "Номер разрешения на работу", который включает или отключает содержащиеся в них редакторы на основе других свойств модели, например, в данном случае "Гражданство". Этого довольно легко достичь при первом получении и рендеринг модели представления.
Однако все становится сложнее, когда пользователь, например, меняет значение "Гражданство". Изменилось только поле пользовательского интерфейса и нет свойства модели, но контейнер, который решает, включен ли "Номер разрешения на работу", зависит от свойства модели.
Я вижу только два решения этого:
Используйте модель представления на стороне клиента (возможно, на JavaScript), соберите модель представления на стороне сервера, возможно, сценарий Knockout.js. Затем обойдите обычную отправку формы и отправьте всю модель на стороне клиента сразу.
Используйте ajax-вызов для обновления модели на стороне сервера, когда пользователь изменяет значение "Гражданство", и обновляйте все части представления, которые зависят от значения "Гражданство". Это усложняет ситуацию, потому что мне нужно иметь "работающую" и "преданную" модель на стороне сервера. Рабочая модель для сохранения небольших изменений, например, только "Гражданство", а затем, когда пользователь нажимает кнопку "Сохранить", чтобы переместить все изменения в "подтвержденную" модель и сохранить в хранилище данных.
Для тех, кто понимает, что я имею в виду, какие другие средства я могу использовать для достижения этой цели, или как я могу улучшить методы, изложенные выше?
1 ответ
Я думаю, что этот сценарий идеально подходит для решения на стороне клиента с использованием нокаута, как вы упомянули в своем первом предложенном решении. Knockout позволяет очень легко выполнять подобные манипуляции с пользовательским интерфейсом на стороне клиента декларативным способом. После того как пользователь заполнил форму, вы просто сериализуете объект модели представления на стороне клиента в JSON и отправляете его на уровень службы.
Ваше второе предлагаемое решение гораздо менее убедительно. Среди его недостатков:
- Для обновления пользовательского интерфейса требуется обратная связь с сервером, что не совсем удобно для пользователя.
- Ваша модель домена сервера теперь должна иметь работающую и фиксированную модель, что увеличивает сложность
Код для реализации этого с помощью нокаута и клиентской модели представления javascript с использованием шаблона MVVM довольно прост:
<div data-bind = "text: name"></div>
<input type="radio" name="citizenship" value="yes" data-bind="checked: citizenship">South African Citizen<br/>
<input type="radio" name="citizenship" value="nowithoutworkpermit" data-bind="checked: citizenship">Non South African, no work permit<br />
<input type="radio" name="citizenship" value="nowithworkpermit" data-bind="checked: citizenship">Non South African, with work permit<br />
<div id="workpermit" data-bind="visible: citizenship() === 'nowithworkpermit'">
<input type="text" name="workpermitinumber" />Work Permit number
</div>
<script src="/Scripts/knockout-2.2.0.js" ></script>
<script>
var MyApp = MyApp || {};
MyApp.ViewModel = {
citizenship: ko.observable(""),
name: ko.observable("John")
};
ko.applyBindings(MyApp.ViewModel);
</script>
В этом примере я создал модель представления в MyApp.ViewModel. Модель имеет два свойства: имя и гражданство. Я связал данные свойством "гражданство" со свойством "проверено" радиобутона, а также со свойством "видимое" отображения текстового поля для номера разрешения на работу.
Когда пользователь проверяет переключатель, нокаут обновляет свойство "гражданство" модели представления. Это изменение в свойстве модели представления, в свою очередь, обновит свойство видимости css для рабочего элемента div с помощью нокаутирующей привязки "visibile". Когда пользователь готов отправить форму, вы просто сериализуете MyApp.ViewModel в JSON и отправляете по сети.
Документация по нокауту выдающаяся ( см. Здесь), и я думаю, что она идеально подходит для того, что вы пытаетесь достичь.