Я хочу повернуть массив, чтобы выбрать вариант с помощью knockout js, я знаю 3 метода для этого случая, но ни один из них не работает идеально с тем, что я действительно хочу, я хочу:
Choose an optionattr для опцийУ каждого метода есть своя проблема, но последний метод имеет параметр по умолчанию и может получить выбранное значение, но не может установить attr, есть идея?
Способ 1:
Ошибка:
Uncaught Error: The binding 'value' cannot be used with virtual elements
Статус: не работает
function myfunc() {
var self = this;
self.estimate = ko.observableArray([]);
self.selectedValue = ko.observable();
var obj = [{
method_title: "blah blah",
price: "1000"
},
{
method_title: "blah blah 2",
price: "2000"
}
];
self.estimate(obj);
self.selectedValue.subscribe(function(value) {
alert(value);
});
}
ko.applyBindings(new myfunc());<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select id = "method">
<option value = "0">Choose an option</option>
<!-- ko foreach: estimate, value: selectedValue -->
<option data-bind = "text: method_title,
attr: { 'data-price': price, 'value': method_title },
text: method_title"></option>
<!-- /ko -->
</select>Способ 2:
Статус: работает, но я не мог добавить параметр по умолчанию, он каждый раз зацикливался.
function myfunc() {
var self = this;
self.estimate = ko.observableArray([]);
self.selectedValue = ko.observable();
var obj = [{
method_title: "blah blah",
price: "1000"
},
{
method_title: "blah blah 2",
price: "2000"
}
];
self.estimate(obj);
self.selectedValue.subscribe(function(value) {
alert(value);
});
}
ko.applyBindings(new myfunc());<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select id = "method" data-bind = "foreach: estimate,value: selectedValue">
<option value = "0">Choose an option</option>
<option data-bind = "text: method_title,attr: {'data-price': price, value: method_title}"></option>
</select>Способ 3:
Статус: работает, но установить attr не удалось
function myfunc() {
var self = this;
self.estimate = ko.observableArray([]);
self.selectedValue = ko.observable();
var obj = [{
method_title: "blah blah",
price: "1000"
},
{
method_title: "blah blah 2",
price: "2000"
}
];
self.estimate(obj);
self.selectedValue.subscribe(function(value) {
alert(value);
});
}
ko.applyBindings(new myfunc());<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select id = "method" data-bind = "value: selectedValue,options: estimate,
optionsText: 'method_title',
optionsValue: 'method_title',
optionsCaption: 'Choose an option'"></select>


![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вам просто нужно немного изменить свой третий метод.
Из официальной документации Нокаут: привязка "вариантов" вы можете использовать параметр optionsAfterRender. Я изменил ваш код. Посмотрим, поможет ли это
function myfunc() {
var self = this;
self.estimate = ko.observableArray([]);
self.selectedValue = ko.observable();
var obj = [{
method_title: "blah blah",
price: "1000",
href: "href 1",
title: "go to href 1"
},
{
method_title: "blah blah 2",
price: "2000",
href: "href 2",
title: "go to href 2"
}
];
self.setOptionAttr = function(option, item) {
if (item)
{
ko.applyBindingsToNode(option, {attr: {href:item.href,title:item.title}}, item);
}
}
self.estimate(obj);
self.selectedValue.subscribe(function(value) {
alert(value);
});
}
ko.applyBindings(new myfunc());<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select id = "method" data-bind = "value: selectedValue,options: estimate,
optionsText: 'method_title',
optionsValue: 'method_title',
optionsCaption: 'Choose an option',
optionsAfterRender: setOptionAttr"></select>Ваш первый метод был наиболее многообещающим, поэтому я исправил это. Вам не нужно использовать связывание value в петле foreach. Его нужно использовать в <select>, и он отлично работает.
function myfunc() {
var self = this;
self.estimate = ko.observableArray([]);
self.selectedValue = ko.observable();
var obj = [{
method_title: "blah blah",
price: "1000"
},
{
method_title: "blah blah 2",
price: "2000"
}
];
self.estimate(obj);
self.selectedValue.subscribe(function(value) {
console.info(value);
});
}
ko.applyBindings(new myfunc());<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select id = "method" data-bind = "value: selectedValue">
<option value = "0">Choose an option</option>
<!-- ko foreach: estimate -->
<option data-bind = "text: method_title,
attr: { 'data-price': price, 'value': method_title }"></option>
<!-- /ko -->
</select>
Имейте в виду, что браузеры могут удалять комментарии из элементов
selectдо того, как Knockout когда-либо их увидит. IE 8, например, делает это.