2016-08-15 2 views
0

Я пытаюсь обновить текстовое поле при изменении значения select.Knockout.js - Обновление текстового поля при изменении выпадающего списка

Теперь я знаю, что это довольно просто, но я не хочу обновлять текстовое поле с помощью простого для получения данных.

Вот что я могу сделать, до сих пор:

  • Поймать событие изменения
  • Получить идентификатор из Выбрать выпадающего списка

Вот что я хочу сделать:

  • Используйте выделенный идентификатор, чтобы вернуть значение свойства из массива объектов внутри моей модели. Однако идентификатор не соответствует индексу массива (т. Е. Выбранный идентификатор может быть «43», но индекс равен 0).

Не так много смысла в публикации моего кода нокаута, поскольку он довольно простой, поэтому вместо этого я опубликую свою структуру VM.

ViewModel 
--> Property1 
--> Property2 
--> Array 
    --> Object[0] 
     --> "Property to match with the selected ID" 
     --> "Property that I want to return" 
    --> Object[1] 

Не уверен, насколько это смысл, надеемся, что это принесет некоторые из них.

Любая другая информация может быть предоставлена.

Спасибо!

EDIT

В.М.

var PurchaseOrderViewModel = function (data) { 
    var self = this; 

    self.UpdateCurrency = function (data, event) { 
     // 
    } 
    self.UpdateSupplierContactDetails = function (data, event) { 
     // 
    } 

    ko.mapping.fromJS(data, {}, self); 
} 

$(document).ready(function() { 
    var viewModel = new PurchaseOrderViewModel(@Html.Raw(jsonString)); 

    ko.applyBindings(viewModel); 
}); 

EDIT # 2

Успели получить работающее решение, в случае, если кто-то есть вопросы, вот как я работал вокруг него.

var contact = ko.unwrap(ko.utils.arrayFirst(self.AllSupplierContacts(), 
    function (item) { 
     return ko.unwrap(item.Id) === newID; 
    }).BusinessTelephoneNumber); 
+3

Там всегда точка размещения текущего кода, по крайней мере, потому, что мы не должны написать тестовый прибор от нуля только, чтобы иметь что-то работать. Отправьте свой код. Сделайте это (в основном) рабочий пример, viewmodel, data, view, initialization и все. – Tomalak

+0

@JamesThorpe Да, вероятно, плохо сформулировано. Что я имел в виду, так это то, что он по существу является шаблоном, и я пытаюсь расширить его с помощью этой первой функции. Будет редактировать OP с источником. –

ответ

1

Этот ответ состоит из двух частей: код, который я думаю, что вы ищете (1), и код, который я думаю, вы должны написать (2).

1. Нахождение элемента, который соответствует идентификатору

ko.applyBindings(new function() { 
 
    
 
    this.ids = ["A", "B", "C", "D"]; 
 
    this.selectedId = ko.observable(); 
 
    
 
    this.items = [ 
 
    { key: "A", value: 1 }, 
 
    { key: "B", value: 2 }, 
 
    { key: "C", value: 3 }, 
 
    ]; 
 
    this.selectedValue = ko.pureComputed(function() { 
 
    var selectedId = this.selectedId(); 
 
    
 
    // Find the object in items of which the property 
 
    // `key` matches the `selectedId` and return it 
 
    var match = this.items.find(function(item) { 
 
     return item.key === selectedId; 
 
    }); 
 
    
 
    return match ? match.value : "No item found"; 
 
    }, this); 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<select data-bind="options: ids, value: selectedId"></select> 
 

 
<div> 
 
    Your selected value: <strong data-bind="text: selectedValue"></strong> 
 
</div>

2. Привязывание фактических элементов на выбор:

Нокаут-х options связывание делает многие вещи из коробки. Вам, вероятно, не нужно хранить ids и items отдельно.Рассказывая переплет, какое свойство должно оказывать в выпадающем списке (optionsText), и для сохранения в качестве значения (optionsValue), вам потребуется намного меньше кода, чтобы сделать то же самое:

ko.applyBindings(new function() { 
 
    
 
    this.items = [ 
 
    { key: "A", value: 1 }, 
 
    { key: "B", value: 2 }, 
 
    { key: "C", value: 3 }, 
 
    { key: "D", value: 4 } 
 
    ]; 
 
    
 
    this.selectedValue = ko.observable(); 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<select data-bind="options: items, 
 
        optionsText: 'key', 
 
        optionsValue: 'value', 
 
        value: selectedValue"></select> 
 

 
<div> 
 
    Your selected value: <strong data-bind="text: selectedValue"></strong> 
 
</div>

+0

'new function()' ?? – Tomalak

+0

Это просто сокращение для 'var ViewModel = function() {/ * ... * /}; var vm = new ViewModel(); ' – user3297291

+0

Спасибо за комментарий. Мне удалось решить эту проблему, я понятия не имел, что ko.utils.arrayFirst существует! –

0

Вся проблема «поиска идентификатора в массиве» может быть отброшена при отсутствии работы с идентификаторами вообще, но с самими элементами массива.

function MyList(params) { 
 
    var self = this; 
 

 
    // observables 
 
    self.items = ko.observableArray(); 
 
    self.selectedItem = ko.observable(); 
 

 
    // init 
 
    ko.mapping.fromJS(params, {}, self); 
 

 
    // post-init 
 
    self.items.sort(function (a, b) { 
 
     return ko.unwrap(a.key) < ko.unwrap(b.key) ? -1 : 1; 
 
    }); 
 
} 
 

 
ko.applyBindings(new MyList({ 
 
    items: [ 
 
     { key: "D", id: 4 }, 
 
     { key: "A", id: 3 }, 
 
     { key: "B", id: 2 }, 
 
     { key: "C", id: 1 } 
 
    ] 
 
})); 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script> 
 

 
<select data-bind=" 
 
    optionsCaption: 'Please select...', 
 
    options: items, 
 
    optionsText: 'key', 
 
    value: selectedItem 
 
"></select> 
 

 
<div data-bind="with: selectedItem"> 
 
    Your selected value: <strong data-bind="text: id"></strong> 
 
</div> 
 

 
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

+0

Не этот ответ в основном является копией подхода, который я рекомендую во второй части моего ответа здесь: http://stackoverflow.com/a/38957151/3297291? Я пропустил важную разницу? – user3297291

+0

Подход, да. У меня было это в работах, пока вы отправляли свои. Различия в деталях. Я выделил их в своем комментарии ниже вашего ответа. – Tomalak