ObservableArray для выбора опции в KnockOut JS

Я хочу повернуть массив, чтобы выбрать вариант с помощью knockout js, я знаю 3 метода для этого случая, но ни один из них не работает идеально с тем, что я действительно хочу, я хочу:

  1. Установить вариант по умолчанию Choose an option
  2. получить выбранное значение
  3. установить attr для опций

У каждого метода есть своя проблема, но последний метод имеет параметр по умолчанию и может получить выбранное значение, но не может установить 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>

Имейте в виду, что браузеры могут удалять комментарии из элементов select до того, как Knockout когда-либо их увидит. IE 8, например, делает это.

connexo 01.11.2018 08:28
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
810
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вам просто нужно немного изменить свой третий метод.

Из официальной документации Нокаут: привязка "вариантов" вы можете использовать параметр 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>

Другие вопросы по теме