Как правильно обрабатывать выборки в ractivejs?

Мы ищем (пере) создание веб-приложения. Мы хотели бы сделать его изоморфным, чтобы сервер мог отображать те же шаблоны, но модель состояния javascript могла бы существовать и обрабатывать обновления. Рассматриваю ractivejs и усы / рули как один довольно многообещающий вариант.

Однако я столкнулся с проблемой. Большая часть нашего сайта в основном формы с расширенной функциональностью. У нас есть несколько полей, но затем может быть много строк данных, для которых нужно отобразить каждое поле. Некоторые поля имеют зависимые поля: например, поле, представляющее собой список стран, может иметь зависимое состояние поля: для некоторых стран поле состояния не существует, а для других оно существует, но имеет различные возможные значения в зависимости от страны. ,

Например, у нас могут быть следующие данные

{
"data": [{
"firstName": "Joe",
"lastName": "Bloggs",
"travelDocument": "PASS BOOK",
"issueCountry": "US",
"issueState": "CA",
"iterator_row_num": "0"},
{
"firstName": "Anne",
"lastName": "Other",
"travelDocument": "ID",
"expiryDate": "2021-01-02",
"issueDate": "1921-03-04",
"iterator_row_num": "1"}],
"fields": {
"firstName": {
"type": "text",
"isList": false,
"isDate": false
},
"lastName": {
"type": "text",
"isList": false,
"isDate": false
},
"travelDocument": {
"type": "list",
"possibleValues": [{
"name": "Passport",
"dependentFields": [{
"name": "Issue Country",
"type": "list",
"possibleValues": [{
"name": "\u00c5land",
"value": "AX"},
{
"name": "Finland",
"value": "FI"},
{
"name": "Sweden",
"value": "SV"},
{
"name": "United States",
"dependentFields": [{
"name": "Issue State",
"type": "list",
"possibleValues": [{
"name": "Alaska",
"value": "AL"},
{
"name": "California",
"value": "CA"},
{
"name": "New York",
"value": "NY"}],
"isList": true,
"isDate": false,
"fieldName": "issueState"}],
"value": "US"}],
"isList": true,
"isDate": false,
"fieldName": "issueCountry"},
{
"name": "Expiry Date",
"type": "date",
"isList": false,
"isDate": true,
"fieldName": "expiryDate"}],
"value": "PASS BOOK"},
{
"name": "ID Card",
"dependentFields": [{
"name": "Expiry Date",
"type": "date",
"isList": false,
"isDate": true,
"fieldName": "expiryDate"},
{
"name": "Issue Date",
"type": "date",
"isList": false,
"isDate": true,
"fieldName": "issueDate"}],
"value": "ID"}],
"isList": true,
"isDate": false
}
}
}

У меня были некоторые проблемы с <select> элементы для полей типа списка. То, что я хотел сделать в шаблоне, было что-то вроде:

{{#data}}
<input type="text" value="{firstName}" name="firstname[{{iterator_row_num}}]" />
<input type="text" value="{lastName}" name="lastname[{{iterator_row_num}}]" />
<select name="travelDocument[{{iterator_row_num}}]">
{{#fields.travelDocument.possibleValues}}
<option value="{{value}}"{{#if value == travelDocument }}
selected
{{/if}}
>{{name}}</option>
{{/fields.travelDocument.possibleValues}}
</select>
{{#fields.travelDocument.possibleValues}}
{{#if value == travelDocument}}
dependent fields here
{{/if}}
{{/fields.travelDocument.possibleValues}}
{{/data}}

Но усы не позволяют, если с сравнениями. Я попытался добавить внутренний счетчик в мою модель данных и функцию приращения в начале каждого цикла. Эта функция в основном прошла через поля и добавила / обновила логическое значение isCurrent свойство для каждого возможного значения на основе текущих данных. Это работает в PHP, но затем мне пришлось повторить мои функции приращения в слое js. И я не могу заставить его работать. Кажется, чтобы установить все строки на основе первого для зависимых полей

Мой шаблон тогда выглядел примерно так:

{{initLoop}}
{{#data}}
{{advanceLoop}}
<input type="text" value="{firstName}" name="firstname[{{iterator_row_num}}]" />
<input type="text" value="{lastName}" name="lastname[{{iterator_row_num}}]" />
<select name="travelDocument[{{iterator_row_num}}]">
{{#fields.travelDocument.possibleValues}}
<option value="{{value}}"{{#isCurrent }}
selected
{{/isCurrent}}
>{{name}}</option>
{{/fields.travelDocument.possibleValues}}
</select>
{{#fields.travelDocument.possibleValues}}
{{#isCurrent}}
{{#dependentFields}}
dependent fields here
{{/dependentFields}}
{{/isCurrent}}
{{/fields.travelDocument.possibleValues}}
{{/data}}

я имею indexN (целое число) и fixedIndex (логические) свойства в моей модели данных. initLoop функция просто устанавливает indexN до -1.

У меня тогда есть функции, немного похожие на:

data._set_current_name = function() {
this._currentName = false;
if( this.data[this.indexN] !== undefined ) {
this._currentName = this.data[this.indexN];
}
for( var field_id in this.fields ) {
this._update_field_values(field_id, this.fields[field_id]);
}
};
data._get_current_val = function(field_id) {
var currentVal = '';
if( false !== this._currentName && this._currentName[field_id] !== undefined ) {
currentVal = this._currentName[field_id];
}
return currentVal;
};
data._update_field_values = function(field_id, field) {
var currentVal = this._get_current_val(field_id);
switch( field.type ) {
case 'list':
if( field.possibleValues ) {
for( var posVal_i in field.possibleValues ) {
var posVal = field.possibleValues[posVal_i];
posVal.isCurrent = ( posVal.value === currentVal );
if( posVal.dependentFields ) {
for( var depField_i in posVal.dependentFields ) {
var depField = field.possibleValues[posVal_i].dependentFields[depField_i];
this._update_field_values(depField.fieldName, field.possibleValues[posVal_i].dependentFields[depField_i]);
}
}
}
}
break;
default:
field.currentValue = currentVal;
break;
}
};
data.advanceNameLoop = function() {
if( !this._fixedCounters ) {
++this.indexN;
}
this._set_current_name();
return '';
};

Мы также хотим, чтобы он автоматически обновлял, какие зависимые поля отображаются при изменении значения «родительского» поля. Попытка добавить наблюдателя на стороне рактива, который устанавливает индексы для текущей строки, но не полностью. Кроме того, изменение выбора даже не вызывает его, в то время как изменение текстового поля делает? (Пробовал с наблюдателем как на избранном, так и на .* чтобы получить все поля).

Мой наблюдатель выглядел так:

names.observe('data.*.*', function(newValue, oldValue, keyPath){
var pathParts = keyPath.split('.');
this.viewmodel.data.setNameIndexes(pathParts[2]);
});

setNameIndexes является:

data.setNameIndexes = function(nameIndex) {
this.indexN= nameIndex;
this._fixedCounters = true;
};

Я даже в правильном направлении здесь? Как следует обрабатывать массив данных для нескольких полей. Учитывая, что некоторые поля (например, страна) могут иметь много возможных значений, я действительно хочу избегать создания отдельной копии целого поля для каждой строки данных. Это кажется странным, если нет лучшего способа обработки селектов в усах

(Примечание: это упрощенная версия того, что у меня есть: у нас есть классификация данных, поэтому у меня есть двойной индекс (категория, а затем имя) и много других полей. Из-за этого могут быть небольшие ошибки)

2

Решение

Вам не нужно вручную устанавливать выбранный атрибут для тега с ractive. Смотрите часть на <select> элементы здесь: http://docs.ractivejs.org/latest/two-way-binding

Кратко рассмотрев ваш JSON сверху и то, что вы пытаетесь сделать, это должно сделать это:

{{#each data}}
...
<select name="travelDocument{{iterator_row_num}}" value="{{travelDocument}}">
{{#each possibleValues}}
<option value="{{value}}">{{name}}</option>
{{/each}}
</select>
{{/each}}

Это будет синхронизировать data [i] .travelDocument со значением его блоков выбора.

Для второй части вашего вопроса, показаны зависимые поля на основе выбранного travelDocument …

    {{#each fields.travelDocument.possibleValues}}
{{#if value == travelDocument}}
{{#each dependentFields}}
I am a {{type}} named {{name}} <!-- you get the point -->
{{/each}}
{{/if}}
{{/each}}

Есть несколько способов сделать это, но это должно помочь вам начать.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]