Sustain dropdown on row while table refreshes

2019-07-23 19:55发布

问题:

I have a table which refreshes every few seconds. On each row, I have a dropdown (from ui.bootstrap) which allows the user to perform actions on that row.

The issue is that upon getting new data from the DB, if the dropdown is open, it closes. This is quite annoying for the users.

I did originally just have separate buttons on the row to perform the actions, but I can see that the list of actions is likely to grow, so would like to move to a dropdown.

    <tbody ng-repeat="item in items">
        <tr>
            <td>{{item.name}}</td>
            <td>{{item.age}}</td>
            <td>
                <div class="btn-group" dropdown>
                    <button type="button" class="btn btn-sm btn-primary">Action</button>
                    <button type="button" class="btn btn-sm btn-primary" dropdown-toggle>
                        <span class="caret"></span>
                        <span class="sr-only">Split button!</span>
                    </button>
                    <ul class="dropdown-menu" role="menu">
                        <li><a>Edit</a>
                        </li>
                        <li><a href="#">Delete</a>
                        </li>
                        <li><a href="#">Something else here</a>
                        </li>
                        <li class="divider"></li>
                        <li><a href="#">Separated link</a>
                        </li>
                    </ul>
                </div>
            </td>
        </tr>
    </tbody>

I've done a plunkr to demonstrate here, probably easier than be waffling on! If you click a dropdown and wait a few seconds, you'll see it disappear.

Any advise is very much appreciated.

Edit: Thanks to Denocle for his answer, here... plunkr

...and also I've refined his method slightly without using IDs in the DOM, here... plunkr

Thanks for the help and comments.

回答1:

As long as you have a unique ID to all your rows, you can save the ID of the row that you have the dropdown open for, before you refresh, and then find that row after the data has updated to the add the "open" class to the btn-group on that row.

I forked your demonstration with a working example here: http://plnkr.co/edit/6vwBnmbsJQvDxHoxLJ70

// Method for saving and restoring the correct dropdown

api.saveOpenBtnGroup = function() {
  this.openBtnGroupItemId = null;
  var openBtnGroup = document.getElementsByClassName('btn-group open');
  if (openBtnGroup.length > 0) {
    this.openBtnGroupItemId = openBtnGroup[0].getAttribute('data-item-id');
  }
}

api.restoreOpenBtnGroup = function() {
  if (this.openBtnGroupItemId !== null) {
    var btnGroup = document.querySelectorAll('[data-item-id="' + this.openBtnGroupItemId + '"]');
    if (btnGroup.length == 1) {
      console.log(btnGroup[0].className);
      btnGroup[0].className = btnGroup[0].className + ' open';
      console.log(btnGroup[0].className);
    }
  }
}
<!-- Adding the unique item id to the btn-group so we can find it later -->
<div class="btn-group" dropdown data-item-id="{{item.id}}">



回答2:

Just as an alternative, if you just change the contents of the array, opposed to changing the array itself, the dropdown will remain open:

function getItems() {
    $scope.i++;
    console.log("refresh");
    //$scope.items = api.getStuff();
    angular.forEach($scope.items, function(item){
      item.age = Math.floor((Math.random() * 100) + 1);
    })
}