Angular UI-Bootstrap typehead в таблице

На самом деле простой вопрос, но как я могу настроить ввод текста для работы в таблице, которая работает с другой таблицей, чем мой ввод?

Например, у меня есть внешний ключ в таблице, и я хочу, чтобы пользователи могли выбирать этот ключ на основе соответствующего значения NAME в первичной таблице внешнего ключа.

Пример кода:

 <table class="table table-bordered table-hover table-striped rwd-table" id="page-wrap">
<thead>
    <tr>
        <th>Primary ID</th>
        <th>Foreign Key (As Name)</th>
    </tr>
</thead>
<tbody>
    <tr ng-repeat="p in PrimaryTable" id="display">
        <td data-th="ID">{{p.PrimaryID}}</td>
        <td>
            <input id="ForeignKeyName"
                   type="text"
                   ng-model="p.ForeignKeyID"
                   uib-typeahead="f.ForeignKeyID as f.ForeignKeyName for f in ForeignKeyTable | filter:$viewValue"                               
                   class="form-control">
        </td>                   
    </tr>
</tbody>

With this example, I would want the users to see the "Foreign Key (As Name)" As the Name value instead of the ID value. The trick is that I also want the underlying value to be the ID and have it mapped to match the original value, as notified by the ng-model.

ОБНОВЛЕНИЕ: Еще один вопрос, который у меня возник, был связан с предыдущим: как мне настроить мою ng-модель, чтобы отображать ForeignKeyTable.ForeignKeyName вместо PrimaryTable.ForeignKeyID?

Это было бы похоже (я думаю) на то, как uib-typeahead соответствует ForeignKeyTable.ForeignKeyID и ForeignKeyTable.ForeignKeyName, но с двумя отдельными таблицами?

Чего бы я хотел, так это иметь возможность поставить ng-model: PrimaryTable.ForeignKeyID as ForeignKeyTable.ForeignKeyName


person Austin    schedule 26.04.2017    source источник
comment
Я не очень понимаю концепцию здесь. Можете ли вы поделиться примерами данных, хранящихся в PrimaryTable и ForeignKeyTable? Они как-то связаны?   -  person nocodename    schedule 27.04.2017
comment
В основном основная таблица содержит столбец, который ссылается на столбец идентификатора идентификации ForeignKeyTable. Другими словами, строка из PrimaryTable может быть {ID:1, ForeignKeyID: 18, ...}, а соответствующая строка ForeignKeyTable может быть {ForeignKeyID: 18, ForeignKeyName: 'Apple', ...}. С этими данными я в основном хочу, чтобы пользователи могли вводить/выбирать «Apple», а соответствующее значение, которое использует таблица, должно быть 18.   -  person Austin    schedule 27.04.2017
comment
но должно ли это 18 быть значением из PrimaryTableRow.ForeignKeyID или ForeignKeyTableRow.ForeignKeyID?   -  person nocodename    schedule 27.04.2017
comment
Начальное значение для столбца будет основано на PrimaryTableRow.ForeignKeyID для этой строки. Таким образом, если строка содержит 18 в столбце ForeignKeyID, она будет использоваться в качестве отправной точки. Затем я хочу, чтобы пользователь мог выбирать из списка на основе ForeignKeyTable, и в этот момент любой выбор заменял бы значение 18 из PrimaryTable любым соответствующим ForeignKeyTableRow.ForeignKeyID из ForeignKeyTableRow.ForeignKeyName, выбранным пользователем.   -  person Austin    schedule 27.04.2017


Ответы (1)


Первым делом будет обновляться PrimaryKeyTable строк каждый раз, когда пользователь выбирает значение в typeahead. Вам придется поймать выбранный элемент и вручную присвоить его значение ForeignKeyId строке PrimaryTable. Способ сделать это — добавить директиву typeahead-on-select к вашему typeahead и связать ее с функцией, которая присваивает вам значения.

Это будет выглядеть так:

HTML

<tr ng-repeat="p in PrimaryTable" id="display">
    <td data-th="ID">{{p.PrimaryID}}</td>
    <td>
        <input id="ForeignKeyName"
                   type="text"
                   ng-model="selectedItem" <!-- could be anything really for we will not use it here -->
                   uib-typeahead="f.ForeignKeyID as f.ForeignKeyName for f in ForeignKeyTable | filter:$viewValue"   
                   typeahead-on-select="onSelect($item, $model, $label, p)"                            
                   class="form-control">
    </td>                   
</tr>

Внутри контроллера

$scope.onSelect = function($item, $model, $label, primaryKeyTableRow) {
    primaryKeyTableRow.ForeignKeyId = $item.ForeignKeyId;
}

Следующим шагом является отображение значения свойства name строки ForeignKeyTable, которое соответствует ForeignKeyId из PrimaryKeyTable в каждой строке. Поскольку нам нужно отфильтровать ForeignKeyTable, чтобы найти подходящий элемент, было бы неплохо поместить эту логику в контроллер. Поскольку есть несколько строк, в которых мы хотим отобразить соответствующее имя, нам придется фильтровать ForeignKeyTable для каждой строки отдельно. Вот где ng-controller для ng-repeat пригодится. Что мы сделаем, так это привяжем новый контроллер для каждой строки таблицы, сгенерированной ng-repeat, и поместим некоторую логику внутри этого контроллера. В HTML это будет выглядеть так:

<tr ng-repeat="p in primaryKeyTable" ng-controller="itemController">
    <!-- ... -->
</tr>

И нам нужно будет определить новый контроллер в JS-файле:

app.controller('itemController', function() {
    // ...
});

Теперь у нас может быть отдельная логика для каждой строки в таблице. Так что это место для фильтрации ForeignKeyTable, чтобы найти соответствующий элемент и отобразить его имя.

Поскольку весь код довольно большой, я поместил его в плункер: http://plnkr.co/edit/xccgnpxoPHg6vhXWPwZn?p=preview

Посмотрите, что вы можете с этим сделать.

person nocodename    schedule 27.04.2017
comment
Спасибо, это устраняет проблему, с которой я столкнулся при назначении правильного идентификатора при выборе из раскрывающегося списка. У меня все еще есть проблема с ng-model, показывающим ForeignKeyTable.ForeignKeyName вместо PrimaryTable.ForeignKeyID в фактической таблице. Есть ли простой способ сделать это? Я пробовал ng-model = $label, но это не работает. - person Austin; 27.04.2017
comment
Не могли бы вы обновить вопрос, чтобы я мог увидеть код? - person nocodename; 27.04.2017
comment
Я обновил вопрос, надеюсь, это поможет объяснить, что я ищу. По сути, я просто хочу, чтобы ForeignKeyName отображалось вместо ForeignKeyID, которое у меня было ранее в моей ng-модели. - person Austin; 27.04.2017
comment
Если я вас правильно понял, вы должны изменить ng-model="p.ForeignKeyID" на что-то другое, например ng-model="selectedKey". - person nocodename; 27.04.2017
comment
Это не позволило бы мне связать идентификатор с именем при начальной загрузке таблицы. Когда таблица загружается, если p.ForeignKeyID равно 10, я бы хотел, чтобы текстовое поле отображало f.ForeignKeyName с идентификатором ForeignKeyID = 10. И поскольку я хочу это для каждой строки, я подумал, что ng-модель — это способ сделать это. Установив ng-model = "selectedKey", он не отображает для меня значения имени, пока я не внесу изменения. - person Austin; 27.04.2017
comment
Я обновил ответ. Надеюсь, что это поможет вам ;) - person nocodename; 27.04.2017
comment
Спасибо за постоянную помощь. Я пробую это, но мне нужно немного перевести его, чтобы он соответствовал моему текущему макету, поскольку я использую несколько дополнительных инструментов, которые работают с контроллерами ($routeProvider ngRoute), и вернусь, чтобы посмотреть, работает ли это для меня. - person Austin; 28.04.2017
comment
Хорошей новостью является то, что я заставил его работать (несколько). Плохая новость заключается в том, что это работает только иногда, и я думаю, что это связано с тем, что я загружаю свои таблицы через API. Проблема в том, что код попадает в getForeignKeyItem(), а $scope.ForeignKeyTable по-прежнему пуст, и произойдет сбой, если я не поставлю оператор If раньше. Это работает (в некоторой степени), если мои таблицы достаточно велики, что замедляет загрузку страницы на несколько секунд, чего я тоже не обязательно хочу. Я собираюсь искать способ ускорить вызовы API, возможно, переходя на асинхронность, но в любом случае я застрял. - person Austin; 01.05.2017
comment
Хорошо. Я, вероятно, не должен, потому что это не входит в объем исходного вопроса, но вот: plnkr. co/edit/Ey0O1yi8w4DtFUL1zQ7H?p=preview Я использовал метод $http.get() для извлечения таблиц из файлов json. И назначать их асинхронно. - person nocodename; 01.05.2017
comment
Большое спасибо, ng-if в сочетании с логическим изменением в .then было тем, чего мне не хватало. Я больше не буду задавать здесь вопросы, и если у меня возникнут какие-либо другие проблемы, я открою новый вопрос. Еще раз спасибо за всю помощь. - person Austin; 02.05.2017