knockout: observable array not getting binded properly — only 1 result being shown while api returns 6

Html код с нокаутирующей привязкой

$(document).on('click', 'div.toggleCarousel', function () {
                D_usedSearch.similarCarsCarousel.showCarousel($(this));
            });

showCarousel: function (toggleBtn) {
            var carouselMain = toggleBtn.parent().find('div.similarCarCarousel');
            var carouselList = carouselMain.find('li');

                $.ajax({
                    url: '/webapi/profileRecommendations/',
                    type: 'GET',
                    data: 'profileId=' + toggleBtn.parents('li').find('a').eq(3).attr('profileid'),
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    beforeSend: function (xhr) { xhr.setRequestHeader('sourceid', '1'); },
                    success: function (response) {
                        D_usedSearch.similarCarListings(response);
                    }
                });
              });
        }

похожие списки: ko.observableArray([])

Api возвращает 6 объектов, но в пользовательском интерфейсе отображается только один.

Может ли кто-нибудь сказать мне, где я ошибаюсь? Я новичок в нокауте? нужно ли применять привязку или делать что-то еще?

1 ответ

  1. В вашем HTML вы написали эту привязку данных:

    foreach: D_usedSearch.similarCarListings
    

    То<li>, что приходит после этой привязки данных действует как шаблон, который knockout использует для отображения элемента списка для каждого элемента в массиве с именем similarCarListings.

    Knockout не будет касаться HTML, пока вы не скажете ему сделать это, позвонив ko.applyBindings. Этот метод нуждается по крайней мере в одном аргументе: «Viewmodel», который содержит всю информацию, необходимую для отображения пользовательского интерфейса.

    Для работы написанной привязки данных потребуется по крайней мере следующая модель viewmodel (VM) :

    var vm = {
      D_usedSearch: {
        similarCarListings: ko.observableArray([])
      }
    };
    
    ko.applyBindings(vm);
    

    В successобработчике вы предоставляете наблюдаемому массиву новые элементы:

    success: function (response) {
      vm.D_usedSearch.similarCarListings(response);
    }
    

    Дайте мне знать,если это поможет. Если привязки еще не применены, могут возникнуть ошибки…

    Вот пример нокаута без всех вещей, которые не имеют ничего общего с нокаутом:

    var exampleServerData = [{
      ProfileId: "0",
      CarName: "Car Name 0",
      OriginalImgPath: "http://img.carwale.com/used/no-cars.jpg",
      Price: "1000$",
      Url: "http://stackoverflow.com",
      Km: "40000",
      Fuel: "LPG",
      MakeYear: "2000",
      AreaName: "Area 0",
      CityName: "City 0"
    }, {
      ProfileId: "1",
      CarName: "Car Name 1",
      OriginalImgPath: "http://img.carwale.com/used/no-cars.jpg",
      Price: "2000$",
      Url: "http://stackoverflow.com",
      Km: "30000",
      Fuel: "LPG",
      MakeYear: "1000",
      AreaName: "Area 1",
      CityName: "City 1"
    }];
    
    
    var vm = {
      D_usedSearch: {
        similarCarListings: ko.observableArray([])
      }
    };
    
    ko.applyBindings(vm);
    
    
    // This goes in your success callback
    vm.D_usedSearch.similarCarListings(exampleServerData);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    
    <ul data-bind="foreach: D_usedSearch.similarCarListings">
    
      <li data-bind="attr: { id: 'SimilarListing-' + $index() }">
    
        <img data-bind="attr: { 
                        profileId: ProfileId, 
                        alt: CarName, title: CarName, 
                        'src': OriginalImgPath }">
    
        <div data-bind="text: Price"></div>
        <a data-bind="attr: { href: Url }, text: CarName"></a>
    
        <p>
          <span data-bind="text: Km + ' km'"></span>
          <span data-bind="text: Fuel"></span>
          <span data-bind="text: MakeYear"></span>
        </p>
        <p>
          <span data-bind="text: AreaName"></span>
          <span data-bind="text: CityName"></span>
        </p>
      </li>