Как отображать текст в цикле с нокаутом JS - PullRequest
0 голосов
/ 27 ноября 2018

Как отображать текст и год в DIV-цикле при выборе марки и модели с помощью knocoutJs

Как это

Mercedes> C

* C-180

*2016* 1009 *


* C-200

*2015* 1014 *

HTML

<select data-bind="options: manufacturers, optionsCaption:'Brand', optionsText: 'text', optionsValue: 'value', value: selectedManufacturer"></select>
<select data-bind="options: models, optionsCaption:'Model', optionsText: 'text', optionsValue: 'value', value: selectedModel, enable: models().length"></select>

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-debug.js">

JavaScript (KnockoutJS)

function ViewModel(items) {
    this.manufacturers = ko.observableArray(items);
    this.selectedManufacturer = ko.observable();
    this.selectedModel = ko.observable();

    function getById(items, value) {
        if(!value) {
            return [];
        }

        var result = ko.utils.arrayFirst(items, function(item) {
            return item.value === value;
        });

        return result && result.childItems || [];
    }

    this.models = ko.computed(function(){
        var items = this.manufacturers();
        var id = this.selectedManufacturer()
        return getById(items, id);
    }, this);
}

var items = [
    { text: 'Ford', value: 1, childItems:
     [
         { text: 'Mustang', value: 1, childItems:
          [
              { text: 'Shelby GT 350', year: "2015", value: 1, childItems: [] },
              { text: 'Shelby GT 500', year: "2017", value: 2, childItems: [] }
          ]
         },
         { text: 'Focus', value: 2, childItems:
          [
              { text: 'Focus RS', year: "2017", value: 3,  childItems: [] },
              { text: 'Focus S', year: "2014", value: 4,   childItems: [] }
          ]
         }
     ]
    },
    { text: 'Mercedes', value: 2, childItems:
     [
         { text: 'S', value: 5, childItems:
          [
              { text: 'S-400', year: "2018", value: 5, childItems: [] },
              { text: 'S-350', year: "2014", value: 6, childItems: [] }
          ]
         },
         { text: 'C', id: 6, childItems:
          [
              { text: 'C-180', year: "2016", value: 7, childItems: [] },
              { text: 'C-200', year: "2015", value: 8, childItems: [] }
          ]
         }
     ]
    }
];

var module = {};

module.viewModel = new ViewModel(items);

ko.applyBindings(module.viewModel);

1 Ответ

0 голосов
/ 27 ноября 2018

Удалите привязку optionsValue из второго раскрывающегося списка.Теперь selectedModel содержит реальный объект, а не просто идентификатор примитива.

Затем используйте привязку with для привязки к выделению и foreach: childItems для циклического переключения различных параметров.Для рендеринга text и year можно использовать привязку text:

function ViewModel(items) {
    this.manufacturers = ko.observableArray(items);
    this.selectedManufacturer = ko.observable();
    this.selectedModel = ko.observable();

    function getById(items, value) {
        if(!value) {
            return [];
        }

        var result = ko.utils.arrayFirst(items, function(item) {
            return item.value === value;
        });

        return result && result.childItems || [];
    }

    this.models = ko.computed(function(){
        var items = this.manufacturers();
        var id = this.selectedManufacturer()
        return getById(items, id);
    }, this);
}

var items = [
    { text: 'Ford', value: 1, childItems:
     [
         { text: 'Mustang', value: 1, childItems:
          [
              { text: 'Shelby GT 350', year: "2015", value: 1, childItems: [] },
              { text: 'Shelby GT 500', year: "2017", value: 2, childItems: [] }
          ]
         },
         { text: 'Focus', value: 2, childItems:
          [
              { text: 'Focus RS', year: "2017", value: 3,  childItems: [] },
              { text: 'Focus S', year: "2014", value: 4,   childItems: [] }
          ]
         }
     ]
    },
    { text: 'Mercedes', value: 2, childItems:
     [
         { text: 'S', value: 5, childItems:
          [
              { text: 'S-400', year: "2018", value: 5, childItems: [] },
              { text: 'S-350', year: "2014", value: 6, childItems: [] }
          ]
         },
         { text: 'C', id: 6, childItems:
          [
              { text: 'C-180', year: "2016", value: 7, childItems: [] },
              { text: 'C-200', year: "2015", value: 8, childItems: [] }
          ]
         }
     ]
    }
];

var module = {};

module.viewModel = new ViewModel(items);

ko.applyBindings(module.viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<select data-bind="options: manufacturers, optionsCaption:'Brand', optionsText: 'text', optionsValue: 'value', value: selectedManufacturer"></select>
<select data-bind="options: models, optionsCaption:'Model', optionsText: 'text', value: selectedModel, enable: models().length"></select>

<div data-bind="with: selectedModel">

  <ul data-bind="foreach: childItems">
    <li>
      <p data-bind="text: text"></p>
      <p data-bind="text: year"></p>
    </li>
  </ul>

</div>

Обратите внимание, что вы можете использовать тот же подход в вашей первой части логики.Удалите привязку optionsValue и используйте фактическую ссылку на объект в качестве выбора.Это позволяет вам пропустить логику getById все вместе!

function ViewModel(items) {
    this.manufacturers = ko.observableArray(items);
    this.selectedManufacturer = ko.observable();
    this.selectedModel = ko.observable();

    this.models = ko.computed(function(){
        return this.selectedManufacturer() &&
               this.selectedManufacturer().childItems || [];
    }, this);
}

var items = [
    { text: 'Ford', value: 1, childItems:
     [
         { text: 'Mustang', value: 1, childItems:
          [
              { text: 'Shelby GT 350', year: "2015", value: 1, childItems: [] },
              { text: 'Shelby GT 500', year: "2017", value: 2, childItems: [] }
          ]
         },
         { text: 'Focus', value: 2, childItems:
          [
              { text: 'Focus RS', year: "2017", value: 3,  childItems: [] },
              { text: 'Focus S', year: "2014", value: 4,   childItems: [] }
          ]
         }
     ]
    },
    { text: 'Mercedes', value: 2, childItems:
     [
         { text: 'S', value: 5, childItems:
          [
              { text: 'S-400', year: "2018", value: 5, childItems: [] },
              { text: 'S-350', year: "2014", value: 6, childItems: [] }
          ]
         },
         { text: 'C', id: 6, childItems:
          [
              { text: 'C-180', year: "2016", value: 7, childItems: [] },
              { text: 'C-200', year: "2015", value: 8, childItems: [] }
          ]
         }
     ]
    }
];

var module = {};

module.viewModel = new ViewModel(items);

ko.applyBindings(module.viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<select data-bind="options: manufacturers, optionsCaption:'Brand', optionsText: 'text', value: selectedManufacturer"></select>
<select data-bind="options: models, optionsCaption:'Model', optionsText: 'text', value: selectedModel, enable: models().length"></select>

<div data-bind="with: selectedModel">

  <ul data-bind="foreach: childItems">
    <li>
      <p data-bind="text: text"></p>
      <p data-bind="text: year"></p>
    </li>
  </ul>

</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...