2014-10-14 2 views
2

Сценарий: Я делаю запрос на сервер для части. Это дает мне эту спину (это псевдо, но представляет собой то, что я смотрю на):Нокаут: Необычный картографический шаблон

{ 
PartNumber : "XYZ", 
Description: "ABCFOO", 
ProductClass: "Widget", 
FieldList:[ 
    {Name: "PROGRAM TYPE", Value: "Program3"}, 
    {Name: "SHIP", Value: false}, 
    {Name: "NOTES", Value: "SomeValue1"} 
], 
MoreStuff : [{ 
    ... 
}] 
} 

Обратите внимание на список FieldList элементов, это в центре внимания здесь.

Сервер также предоставил мне список определенных полей, их типов и значений по умолчанию. Это выглядит так:

[ 
{FieldName : "PROGRAM TYPE", FieldType: "List", Defaults: [{Name:"Program 1", Value: "Program1"},{Name:"Program 2", Value: "Program2"},{Name:"Program 3", Value: "Program3"}]}, 
{FieldName : "SHIP", FieldType : "Boolean", Defaults: []}, 
{FieldName : "NOTES", FieldType: "TextArea", Defaults: []} 
] 

Это происходит в отдельном вызове REST и до загрузки моей Части. Я использую его для создания части HTML-страницы для Части. Вы можете видеть, что они аналогичным образом связаны с разделом FieldList, когда я прошу Part.

Из этого «списка полей» и значений по умолчанию - я генерирую соответствующие HTML-элементы на странице. Если это тип типа Boolean, я создаю флажок - если это список, я создаю SELECT (с параметрами, указанными в Defaults), TextArea - это текстовая область и т. Д. Все работает нормально. Он заканчивает тем, как:

<input data-bind="textInput: PartNumber"/> 
<textarea data-bind="textInput: Description"></textarea> 

<!-- generating fieldlist - i create a pseudo attr because the field name can have spaces--> 
<select field_label="PROGRAM TYPE"> <!-- how the heck do i bind to this??--> 
    <option value="Program1">Program 1</option> 
    <option value="Program2">Program 2</option> 
    <option value="Program3">Program 3</option> 
</select > 
<input type="checkbox" field_label="SHIP" value="true"/> <!-- or this, how to bind to it?!--> 
<!-- end of field list generation --> 

Теперь я беру объект (часть я дал) и положить, что в мой ViewModel - это все работает просто превосходно. Я делаю это легко и просто использую ko.mapping.fromJS(rest_data); Работает отлично.

Связывание данных ducky - для чего я могу связать его. Моя проблема исходит от - как heck я сопоставляю свой FieldList с HTML, который я сгенерировал для полей, которые мне дал сервер?. Мои данные/мой объект viewmodel имеет FieldList в нем, с материалом buncha, который я хочу сопоставить с созданным материалом. Единственный реальный «ключ», который у меня есть, - это самосоздание field_label У меня есть, потому что FieldName сервера может иметь пробелы.

Так что я догадываюсь, что я прошу, у меня есть этот массив FieldList с моей стороны. У меня есть объект Part в моей модели, и все в порядке. Как считать, что FieldList и отобразить его в мой самообразующейся набор полей из другого объекта (то есть., Взять имя FieldList и привязать его к элементу с field_label одного и того же значения?)

Записанный out - это будет выглядеть так: Как сопоставить FieldList с названием «ТИП ПРОГРАММЫ» с HTML-элементом, имеющим поле_значения «ТИП ПРОГРАММЫ».

Я начинаю думать, что это может быть направление, в котором я должен идти: http://jsfiddle.net/MhdZp/128/ но он проходит над моей головой.

ответ

1

Один из способов приблизиться к этому:

function Option(definition) { 
    this.definition = definition; 
    this.value = ko.observable(); 
    this.templateName = 'input-template-' + definition.FieldType; 
} 

function ViewModel() { 
    var self = this; 

    // from REST call 
    var fieldDefinition = [{ 
     FieldName: "PROGRAM TYPE", 
     FieldType: "List", 
     Defaults: [ 
      { Name: "Program 1", Value: "Program1" }, 
      { Name: "Program 2", Value: "Program2" }, 
      { Name: "Program 3", Value: "Program3" } 
     ] 
    }]; 

    self.options = ko.observableArray(); 
    // for the sake of the example 
    self.options.push(new Option(fieldDefinition[0])); 

    // methods  
    self.optionByName = function (name) { 
     return ko.utils.arrayFirst(self.options(), function (option) { 
      return option.Name = name; 
     }); 
    }; 

    // poor man's init, imagine 2nd rest call instead 
    self.optionByName("PROGRAM TYPE").value("Program3"); 
} 

и

<script type="text/html" id="input-template-List"> 
    <label data-bind="text: definition.FieldName"></label> 
    <select data-bind=" 
     value: value, 
     options: definition.Defaults, 
     optionsText: 'Name', 
     optionsValue: 'Value', 
     optionsCaption: 'Please select...' 
    "></select> 
</script> 

и

<div data-bind="foreach: options"> 
    <div data-bind="template: templateName"></div> 
</div> 

Добавить больше шаблонов в случае необходимости, это должно быть очень легко расширить.

jsFiddle: http://jsfiddle.net/0nxt2zte/

+0

я мог бы спутать что-то здесь, но это выглядит как ViewModel был обернут вокруг объекта для HTML-элементов I генерируют (второй JSON) - в котором ViewModel я обернута вокруг первый объект JSON, который я получаю (моя часть). Я читаю ваш код неправильно? Извините, немного измотанный, сегодня суетливый. – Jason

+0

Извините, мне трудно разобрать ваш комментарий. :) Вы посмотрели на скрипку? – Tomalak

+0

Из того, что я понимаю, это выглядит так: ** 1) ** Вы получаете кучу определений полей. ** 2) ** Затем вы создаете кучу элементов ввода в соответствии с этими определениями. ** 3) ** Вы получаете кучу «выбранных значений» через Ajax и хотите связать свои входы с ними. Именно так работает мой код. – Tomalak

Смежные вопросы