Зависимые / каскадные выпадающие списки в Aurelia

#aurelia #dropdown

#aurelia #выпадающий список

Вопрос:

Я хотел бы создать зависимые выпадающие списки в Aurelia.

Что я подразумеваю под зависимыми выпадающими списками, так это то, что если вы нажмете элемент в первом выпадающем списке, то параметры во втором выпадающем списке будут отфильтрованы на основе того, что вы нажмете. Если вы посмотрите на мой js-fiddle, вы заметите, что если вы выберете Toyota в первом выпадающем списке, второй заполняется моделями автомобилей Toyota (Corolla, Camry и т. Д.). Если вы выберете Honda в первом выпадающем списке, второй заполнится моделями Honda (Accord, Civic и т. Д.). Вы поняли идею.

Это очень просто и требует очень мало кода, чтобы сделать это в Angular, и мне было интересно, можно ли сделать это в Aurelia также просто и просто. Я не смог найти много ресурсов о том, как это сделать в Aurelia. Приведенная ниже скрипка демонстрирует именно то, чего я хотел бы достичь (за исключением того, что я хотел бы сделать это в Aurelia, а не в Angular, конечно). Любая помощь будет высоко оценена. Спасибо!

https://jsfiddle.net/nhunt3/wjvvjwzx/

HTML:

 <div ng-app="myApp" ng-controller="myController">
My Cars
<br />
<table>
  <thead>
    <tr>
      <td>Make</td>
      <td>Model</td>
    </tr>
  </thead>

  <tbody>
    <tr ng-repeat="car in myCars track by car.uid">
      <td>
        <select ng-model="car.MakeUID" ng-options="make.uid as make.name for make in makes" />
      </td>

      <td>
        <select
        ng-model="car.ModelUID"
        ng-options="model.uid as model.name for model in models | filter: { parentID: car.MakeUID } : true" />
      </td>
    </tr>
  </tbody>
</table>   
</div>
  

JavaScript:

 // the main (app) module
var myApp = angular.module("myApp", []);

angular.module('myApp', []).controller('myController', function($scope) {
    $scope.makes = [
        {name:'Toyota', uid:1},
        {name:'Honda', uid:2},
        {name:'Ford', uid:3}
    ];

  $scope.models = [
            {name:'Yaris', uid:1, parentID:1},
        {name:'Corolla', uid:2, parentID:1},
        {name:'Camry', uid:3, parentID:1},
        {name:'Highlander', uid:4, parentID:1},
        {name:'Accord', uid:5, parentID:2},
        {name:'Civic', uid:6, parentID:2},
        {name:'Pilot', uid:7, parentID:2},
        {name:'Focus', uid:8, parentID:3},
        {name:'Fiesta', uid:9, parentID:3},
        {name:'Fusion', uid:10, parentID:3},
        {name:'F-150', uid:10, parentID:3}
    ];

  $scope.myCars = [
        {uid:1, MakeUID:1, ModelUID:2},
        {uid:2, MakeUID:1, ModelUID:3},
        {uid:3, MakeUID:3, ModelUID:8}
    ];
});
  

Ответ №1:

Для других пользователей, которые находят этот поток:

app.html

 <template>
  <require from="./filter"></require>
  <table>
  <thead>
    <tr>
      <td>Make</td>
      <td>Model</td>
    </tr>
  </thead>
  <tbody>
    <tr repeat.for="car of myCars">
      <td>
        <select value.bind="car.MakeUID" change.delegate="resetModel(car)">
          <option value="0">select one of ...</option>
          <option repeat.for="make of makes" model.bind="make.uid">${make.name}</option>
        </select>
      </td>
      <td>
        <select value.bind="car.ModelUID">
          <option value="0">select one of ...</option>
          <option repeat.for="model of models | filter:'parentID':car.MakeUID" model.bind="model.uid">${model.name}</option>
        </select>
      </td>
    </tr> 
  </tbody>
</template>
  

app.js

 export class App { 
    makes = [
        {name:'Toyota', uid:1},
        {name:'Honda', uid:2},
        {name:'Ford', uid:3}
    ];

    models = [
        {name:'Yaris', uid:1, parentID:1},
        {name:'Corolla', uid:2, parentID:1},
        {name:'Camry', uid:3, parentID:1},
        {name:'Highlander', uid:4, parentID:1},
        {name:'Accord', uid:5, parentID:2},
        {name:'Civic', uid:6, parentID:2},
        {name:'Pilot', uid:7, parentID:2},
        {name:'Focus', uid:8, parentID:3},
        {name:'Fiesta', uid:9, parentID:3},
        {name:'Fusion', uid:10, parentID:3},
        {name:'F-150', uid:10, parentID:3}
    ];

    myCars = [
        {uid:1, MakeUID:1, ModelUID:2},
        {uid:2, MakeUID:1, ModelUID:3},
        {uid:3, MakeUID:3, ModelUID:8}
    ];

    resetModel(car) {
      car.ModelUID = 0;
    }
}
  

filter.js

 export class FilterValueConverter {
  toView(array, propertyName, filter_on) {
    return array.filter(i => i[propertyName] == filter_on);
  }
}
  

старый ответ

Я думаю, что это делает то же самое, что и ваш угловой код в Aurelia:

 <template>
  <require from="./filter"></require>
  <table>
  <thead>
    <tr>
      <td>Make</td>
      <td>Model</td>
    </tr>
  </thead>
  <tbody>
    <tr repeat.for="car of myCars">
      <td>
        <select value.bind="car.MakeUID" ref="selected_car">
          <option repeat.for="make of makes" value.bind="make.uid">${make.name}</option>
        </select>
      </td>

      <td>
        <select value.bind="car.ModelUID">
          <option repeat.for="model of models | filter:'parentID':selected_car.value">${model.name}</option>
        </select>
      </td>
    </tr> 
  </tbody>
</template>
  

И вам также нужен этот фильтр:

 export class FilterValueConverter {
  toView(array, propertyName, filter_on) {
    return array.filter(i => i[propertyName] == filter_on);
  }
}
  

https://gist.run/?id=91b23375e0b73afe7f21825f67cfeabf

Комментарии:

1. Спасибо, Эрик! Это здорово! У меня есть пара незначительных функций, которых у вас нет, но я уверен, что смогу с ними разобраться. (1) Когда вы выбираете марку в mine, модель выбирает пустую вместо первой модели. (2) когда загружается моя страница, на ней отображаются мои автомобили, то есть Toyota Corolla, Toyota Camry и Ford Focus. Ваш просто показывает Toyota Yaris полностью. Но, как я уже сказал, это незначительно, и вы получили почти все. Огромное спасибо! Я дам ему пару дней, чтобы посмотреть, есть ли какие-либо лучшие ответы, тогда я приму ваши.

2. Я пытался повысить ваш ответ, но в нем говорится, что я не могу повысить голос, пока моя репутация не станет выше.

3. Чем больше я думаю об этом, тем больше я понимаю, что массив myCars, который не выбирается, на самом деле очень важен. MyCars — это то, что будет поступать из базы данных. И значения из базы данных должны отображаться на экране при загрузке страницы. Это очень важно, и я не думаю, что смогу принять ответ, в котором этого нет. Я думаю, что я могу быть частью пути туда. Если вы замените свой первый td в app.html из вашей сути с приведенным ниже (я добавил model.bind=»make.uid» в тег параметров), затем make отображаются при загрузке страницы… Я просто не могу заставить модели отображаться.

4. <td> <select value.bind=»car.MakeUID» ref=»selected_car»> <option/> <option repeat.for=»make of maks» model.bind=»make.uid»>${make.name }</опция> </выбрать> </td>

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

Ответ №2:

Я закончил ваше решение за вас, но вы дали мне очень критическое начало. Я удалил ненужную ссылку в вашем make td и добавил пару model.binds и изменил то, что соответствует вашему фильтру.

Посмотрите мою окончательную суть, которую я разветвил на вашу.

https://gist.run/?id=e0b9c401370a954b594ad2415d983099

Комментарии:

1. Просто сделал то же самое несколько минут назад :-), возвращался домой за время между последним редактированием и этим 🙂 Все еще есть небольшая проблема. Попробуйте выбрать toyata highlander, а затем ford, затем он должен сбросить.

2. Я не уверен, что это можно исправить только из html, но это можно исправить, если car из БД можно преобразовать в класс js с помощью get и setters . Как только вы установите car, сбросьте модель.

3. Смотрите последнюю редакцию этого gist: gist.run/?id=91b23375e0b73afe7f21825f67cfeabf , которая устраняет вышеупомянутую проблему, но для этого вам все равно нужно добавить код в js.

4. Это интересное поведение моей сути … и случается только иногда… странно… Я рассмотрю это завтра и посмотрю, не смогу ли я найти лучшее решение. Ваша функция сброса, безусловно, является хорошим решением на данный момент. Еще раз спасибо за помощь.