Search code examples
javascriptangularjsui-select

$watch changes ui-select in individual object iterated via ng-repeat


I am working with <ui-select> and came across a problem I apparently do not understand how to tackle. There is a bunch of related topics on it here on SO, however, none of them covered my specific problem, which is I think quite simple for people who have worked with this directive before.

I have a big object with item objects inside, like this one:

 let items = [{id: 1, name: 'name'}, {id: 2, name: 'name2'}];

I am iterating over object to make it visible in front. The option will be displayed in

 <ui-select-match allow-clear="true">
      <span>{{ $select.selected.label }}</span>  
 </ui-select-match>

The label will be selected in controller based on the "watched" value. My question here is what should I set in ng-model to watch the changes on the level of individual items and update it?

I tried to use track by index, ng-change instead of watch and a bunch of other approaches which brought no results.

Template:

 <div ng-repeat="item in vm.items">
     <div class="form-group field">
         <label>Items:</label>
         <ui-select ng-model="item.id"
               ng-keyup="vm.newItems({ keyword: $select.search })"
               search-enabled="false">

        <ui-select-match allow-clear="true">
            <span>{{ $select.selected.label }}</span>  
        </ui-select-match>

        <ui-select-choices repeat="item.id as item in vm.shortlistsList">
            <pre>Name: {{ item.label }}</pre><pre>Id: {{ item.id }} </pre>
        </ui-select-choices>
    </ui-select>
</div>

In controller:

 function $onChanges() {
     $scope.$watch('item.id', function (newValue, oldValue) {
         console.log(item.id);
     });
 }

QUESTION: How can I watch each individual item, what/how should I pass to ng-model? At the moment I see no way of doing it as my half day of attempts is gone in vain.


Solution

  • Following a long and painful day of experiments, I found a workable solution:

    Template:

     <div ng-repeat="item in vm.items track by $index">
         <div class="form-group field">
             <label>Items:</label>
             <ui-select ng-model="item[$index]"
                   ng-keyup="vm.newItems({ keyword: $select.search })"
                   search-enabled="false">
    
            <ui-select-match allow-clear="true">
                <span>{{ $select.selected.label }}</span>  
            </ui-select-match>
    
            <ui-select-choices repeat="item.id as item in vm.shortlistsList">
                <pre>Name: {{ item.label }}</pre><pre>Id: {{ item.id }} </pre>
            </ui-select-choices>
        </ui-select>
    </div>
    

    Controller:

       for (let i = 0; i < vm.items.length; i++) {
            $scope.$watch('vm.items[' + i + ']', function (newValue, oldValue) {
                if (newValue && oldValue !== null) {
                    return newValue.label = newValue.name;
                }
            }, true);
        }