Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping objects in angularJS ui.select using "track by"

I want to use angular-ui's ui.select to populate a multiple dropdown field. I'd like to pass the selected objects to the ng-model and have it mapped to my options, containing objects of the same structure, but not from the same source:

<div ng-repeat="training in trainings">
    <form class="form-horizontal" role="form">
        <ui-select multiple ng-model="training.skills" theme="select2" ng-disabled="disabled">
            <ui-select-match placeholder="Wähle Skills...">{{$item.name}}</ui-select-match>
            <ui-select-choices group-by="skillTypeGrp" repeat="skill.id as skill in skills | filter: $select.search">
                <span>{{skill.name}}</span>
            </ui-select-choices>
        </ui-select>
    </form>
</div>

The trainings list from ng-repeat with an example training looks like this:

[{"description": "",
  "skills": [{"type": "tech",
              "name": "C",
              "id": 194}],
  "id": 1,
  "name": "Test"}]

My skills list from ui-select-choices contains the same data structure as in training.skills:

[{"type": "tech",
  "name": "C#",
  "id": 194},
 {"type": "tech",
  "name": "Java",
  "id": 197},
 ...]

Unfortunatly this doesn't work. The ui-select empties my training.skills, showing me an blank select field. I understand that angularjs is not able to map those objects, if they do not origin the same array, like stated in this blogpost. It suggests using track by to tell ui.select which property to use to map the two lists of objects, but if i change the ui-select-choices line to:

<ui-select-choices group-by="skillTypeGrp" repeat="skill.id as skill in skills track by skill.id | filter: $select.search"> 

nothing changes. Is there any possibility to get this running without replacing my objects by their ids like the single property binding example suggests?

like image 510
vnoec Avatar asked Nov 25 '14 10:11

vnoec


2 Answers

You need to reverse filter and track by to make it work:

 <ui-select-choices group-by="skillTypeGrp" repeat="skill in skills | filter: $select.search track by skill.id">

It looks strange, but did the trick for me..

like image 196
madc Avatar answered Nov 13 '22 01:11

madc


If you refer the documentation given at https://docs.angularjs.org/api/ng/directive/ngRepeat the track by must always be the last expression.

So, as suggested by madc if you change to:

 <ui-select-choices group-by="skillTypeGrp" repeat="skill in skills | filter: $select.search track by skill.id">

It would work.

Below is the documentation snippet that says about track by being the last expression:

documentation snippet that says about track by being the last expression

like image 43
Himanshu Arora Avatar answered Nov 13 '22 00:11

Himanshu Arora