Как я могу получить доступ к этому объекту в typeahead?

Я использую twitter typehead с Laravel 5.3. Просто чтобы вы знали, вот мои данные о продукте, а также его бренд производителя (FK):

[
  {
    "id": 2,
    "name": "iphone",
    "created_at": "2017-02-08 06:12:34",
    "updated_at": "2017-02-08 06:12:34",
    "user_id": 1,
    "brand_id": 1,
    "msds_url": "google.com",
    "gravity": 1.03,
    "recipe_id": null,
    "relevance": 210,
    "brand": {
      "id": 1,
      "name": "apple",
      "created_at": "2017-02-08 03:00:49",
      "updated_at": "2017-02-08 03:00:49",
      "user_id": 1,
      "abbreviation": "AP",
      "visible": 1
    }
  }
]

Когда массив JSON удаленного источника сопоставляется с массивом объектов js с именем value, данные в раскрывающемся списке предложений форматируются так, как они написаны, например. «Яблоко — айфон».

var engine = new Bloodhound({
  datumTokenizer: function(datum) {
    return Bloodhound.tokenizers.whitespace(datum.value);
  },
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  remote: {
    wildcard: '%QUERY',
    url: '/find?q=%QUERY%',
    transform: function(response) {
    console.log(response);
      // Map the remote source JSON array to a JavaScript object array
      return $.map(response, function(product) {
        return {
          value: product.brand.name+' - '+product.name,
          other: product
        };
      });
    }
  }
});

// Instantiate the Typeahead UI
$('#search').typeahead( null,{
  display: 'value',//choose a key from the map
  highlight: true,
  hint: true,
  source: engine
});

Что я также хочу сделать, так это привести brand.id, который будет равен 1, и product.id, который будет равен 2, в некоторые атрибуты данных на одном и том же входе, поэтому я зафиксировал событие и зарегистрировал «выбранное предложение», которое принял пользователь.

$("#search").on("typeahead:select", function(ev, suggestion) {
    console.log(suggestion);
});

Проблема в том, что он не дает мне доступа к полному массиву данных, потому что он отформатирован специально в функции карты из части Bloodhound.

// Map the remote source JSON array to a JavaScript object array
          return $.map(response, function(product) {
            return {
              value: product.brand.name+' - '+product.name, //this format
              other: product //full access to object
            };
          });

Поэтому я заменил display на other вместо value, чтобы вместо имени бренда и названия продукта передавался полный объект.

$('#search').typeahead( null,{
  //display: 'value',
  display: 'other',
  highlight: true,
  hint: true,
  source: engine
});

Теперь, когда в раскрывающемся списке появляется предложение, в нем будет указано [object object], потому что я еще не обращался к нему, как раньше.

Как я могу получить доступ к объекту и правильно отформатировать его и сохранить доступ к идентификатору бренда и идентификатору продукта? Это сделано для того, чтобы позже, когда я отправлю форму, я мог сопоставить выбранные идентификаторы продуктов с элементами таблицы продуктов.


person Ashley Brown    schedule 15.02.2017    source источник


Ответы (1)


Хотя я не проверял коды, но у меня это работает в моем проекте. Попробуй это:

var engine = new Bloodhound({
    datumTokenizer: function(datum) {
        var result = Bloodhound.tokenizers.whitespace(datum.name);
        if (datum.brand != null){
            result = result.concat(Bloodhound.tokenizers.whitespace(datum.brand.name));
        }
        return result;
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    remote: {
        wildcard: '%QUERY',
        url: '/find?q=%QUERY%',
        prepare: function(query, settings) {
            settings.type = "GET";
            settings.dataType = "json"
            settings.url = settings.url.replace('%QUERY', encodeURIComponent(query));
            return settings;
        }
    }
});

engine.initialize();

$("#search").typeahead(null, {
    name: 'engine',
    displayKey: function(data){
        return  data.name + (data.brand ? " - " + data.brand.name : "");
    },
    source: engine.ttAdapter(),
})
.on('typeahead:selected', function($e, datum){
    //You may access the value object here
    console.log("datum" ,datum);
});

Дайте мне знать, если работает нормально?

person Dev    schedule 16.02.2017
comment
Работает идеально!!! Пожалуйста, добавьте некоторые пояснения к вашему коду, так как я и, без сомнения, другие захотят понять, как он работает по крупицам. - person Ashley Brown; 16.02.2017
comment
Ну, я реализовал это 3-4 года назад и с тех пор я никогда не просматриваю документацию, так как я никогда не менял эти коды и не нашел в этом никаких проблем, но глядя на ваши коды, я думаю, что проблема была там в map функция, которая манипулирует данными и в инструкции source: engine. - person Dev; 17.02.2017