Выберите сложный объект в выпадающем списке и получите дополнительные данные

Я использую jsViews для создания приложения.

В каком-то месте у меня есть массив сложных объектов. Массив связан в раскрывающемся списке, где я могу установить метку и значение для свойств моего объекта.

Однако мне нужно получить и некоторые другие свойства моего пользовательского объекта.

Как я могу это сделать?

Прямо сейчас у меня есть:

(function($) {
  var dataVm = {
    value: null,
    choices: [
      { "label" : "France", "value" : "FR", "icon" : "flag-icon-fr" },
      { "label" : "Germany", "value" : "DE", "icon" : "flag-icon-de" },
      { "label" : "Brazil", "value" : "BR", "icon" : "flag-icon-br" },
      { "label" : "USA", "value" : "US", "icon" : "flag-icon-us" }
    ],
    icon: "flag-icon-fr"
  };

  var helpers = {
    doSelect : function(){
      // Fake business rule, I.E. call a web service to get country data
      var valueFromBusinessLogic = "FR"; 
      $.observable(dataVm).setProperty("value", valueFromBusinessLogic);
    }
  };

  $.templates("#mainTemplate").link("#container", dataVm, helpers);
})(jQuery);
<link href="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.1.0/css/flag-icon.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsviews/0.9.90/jsviews.min.js"></script>


<script id="mainTemplate" type="text/x-jsrender">
  <p>Selected : <span>{^{:value}}</span></p>
  <p>Flag  : <span data-link="class{:('flag-icon ' + icon)}"></span></p>
  <select data-link='value'>
	{^{for choices}}
   <option value="{{:value}}">{{:label}}</option>
  {{/for}}
	</select>

  <button data-link="{on ~doSelect}">Select from business logic</button>
</script>

<div id="container">

</div>

Это работает, как и ожидалось, но я не могу получить подсвойство icon.

Мое свойство value важно и может быть установлено внешними действиями (инициализация формы или нажатие кнопки). Так что я не могу (по крайней мере, я так думаю), я не могу играть с #index, потому что это поместит индекс в свойство value.


person Steve B    schedule 20.03.2018    source источник


Ответы (1)


Вам нужно решить, что представляет собой выбранное вами свойство страны — это может быть объект, индекс в массиве вариантов или строка значения. Но привязкой выбора по умолчанию является значение.

Если вы сохраните строку значения как выбранную страну, вы можете определить помощник поиска для возврата объекта:

function countryFromVal(val) {
  var i = dataVm.choices.length;
  while (i--) {
    if (dataVm.choices[i].value === val) {
      return dataVm.choices[i];
    }
  }
  return dataVm.choices[0];
}

var helpers = {
    countryFromVal: countryFromVal,

и написать

<span data-link="class{:('flag-icon ' + ~countryFromVal(value).icon)}"></span>

В качестве альтернативы вы можете сделать выбранное свойство страны индексом и использовать конвертеры для выбора, как в этом примере: http://www.jsviews.com/#link-select@selectconvert.

Или вы можете сделать его самим объектом, снова используя преобразователи, например:

(function($) {
  var dataVm = {
    choices: [
      { "label" : "France", "value" : "FR", "icon" : "flag-icon-fr" },
      { "label" : "Germany", "value" : "DE", "icon" : "flag-icon-de" },
      { "label" : "Brazil", "value" : "BR", "icon" : "flag-icon-br" },
      { "label" : "USA", "value" : "US", "icon" : "flag-icon-us" }
    ]
  };

  dataVm.country = dataVm.choices[1];

  function countryFromVal(val) {
    var i = dataVm.choices.length;
    while (i--) {
      if (dataVm.choices[i].value === val) {
        return dataVm.choices[i];
      }
    }
    return dataVm.choices[0];
  }

  function valFromCountry(country) {
    return country.value;
  }

  $.views.converters({
    fromValue: countryFromVal,
    toValue: valFromCountry
  });

  var helpers = {
    doSelect : function(){
      // Fake business rule, I.E. call a web service to get country data
      var valueFromBusinessLogic = "FR"; 
      $.observable(dataVm).setProperty("country", countryFromVal(valueFromBusinessLogic));
    }
  };

  $.templates("#mainTemplate").link("#container", dataVm, helpers);
})(jQuery);
<link href="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.1.0/css/flag-icon.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsviews/0.9.90/jsviews.min.js"></script>

<script id="mainTemplate" type="text/x-jsrender">
  <p>Selected : <span>{^{:country^value}}</span></p>
  <p>Flag  : <span data-link="class{:'flag-icon ' + country^icon}"></span></p>

  <select data-link='{toValue:country:fromValue}'>
    {^{for choices}}
      <option value="{{:value}}">{{:label}}</option>
    {{/for}}
  </select>

  <button data-link="{on ~doSelect}">Select from business logic</button>
</script>

<div id="container"></div>

Обратите внимание на синтаксис country^icon — см. http://www.jsviews.com/#linked-paths@deep

person BorisMoore    schedule 20.03.2018
comment
мой вопрос смутил. Я указал индекс цикла как значение, но он не представляет мой реальный вариант использования. Что делать, если значения не равны индексу? (позвольте мне обновить вопрос, чтобы избежать путаницы) - person Steve B; 20.03.2018
comment
Вопрос обновлен. Теперь значения в элементе выбора не равны индексам - person Steve B; 20.03.2018
comment
Отличный ответ, как всегда. Очень ценю! - person Steve B; 21.03.2018