2016-06-08 46 views
2

我們正在尋找(重新)建立一個網絡應用程序。我們想使它成爲同構的,所以服務器可以呈現相同的模板,但是JavaScript狀態模型將存在並處理更新。我將ractivejs和小鬍子/把手視爲一個頗有前途的選擇。如何處理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; 
}; 

難道我連這裏沿行權?應該如何處理多個字段的數據數組。考慮到一些字段(比如說國家)可能有很多可能的值,我真的希望避免爲每個數據行分配一個整個字段的副本。這似乎很奇怪,如果不是一個更好的方式來處理選擇鬍子/ ractive

(注意:這是我有什麼簡化版本:我們有一個數據的分類,所以我有一個雙重索引(類別然後名稱)和更多的領域。在上面可能會有小錯誤)

回答

0

您不需要手動設置標籤上的選定屬性與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}} 

這將保證數據的[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}} 

有許多方法可以做到這一點,但應該讓你開始。