Поддерживается вместе с Angular.js

Я пытаюсь использовать footable (http://themergency.com/footable-demo/responsive-container.htm) вместе с angular.js.

enter image description here

Когда размер окна уменьшается, столбцы 3, 4, 5 отображаются только при щелчке по знаку плюс.

Angular.js предоставляет возможности фильтрации, поэтому, когда я помещаю некоторую строку поиска, как показано ниже:

enter image description here

Строки в таблице отфильтровываются.

Теперь проблема заключается в том, что я пытаюсь удалить эту строку поиска, как показано ниже:

enter image description here

все строки снова отображаются, но пользовательский интерфейс искажен.

Я попытался получить обратный вызов в angular.js, используя

$scope.$watch('searchStringID', function() {
$('#tableId').trigger('footable_initialize');
}

но не работает, если кто-нибудь может предложить, как решить эту проблему.

Спасибо.

Ответ 1

Чтобы добавить к Даниэль Стаки ответ, вместо добавления каждой отдельной строки каждый раз, когда выполняется ng-repeat, вы можете дождаться завершения ng-repeat и затем инициализировать FooTable на самой родительской таблице:

.directive('myDirective', function(){
  return function(scope, element){
    var footableTable = element.parents('table');

    if( !scope.$last ) {
      return false;
    }

    if (! footableTable.hasClass('footable-loaded')) {
      footableTable.footable();
    }
  };
})

Это намного лучше для таблиц со многими строками.

Примечание element автоматически представляет собой объект jQlite/jQuery, поэтому нет необходимости обертывать его в синтаксисе $().

Обновление

Одним из преимуществ AngularJS является двусторонняя привязка данных. Чтобы синхронизировать данные FooTable с последними данными, вы можете сделать что-то вроде этого:

.directive('myDirective', function(){
  return function(scope, element){
    var footableTable = element.parents('table');


    if( !scope.$last ) {
        return false;
    }

    scope.$evalAsync(function(){

        if (! footableTable.hasClass('footable-loaded')) {
            footableTable.footable();
        }

        footableTable.trigger('footable_initialized');
        footableTable.trigger('footable_resize');
        footableTable.data('footable').redraw();

    });
  };
})

Обертка scope.$evalAsync выполняется, как только DOM готов, но до ее отображения, предотвращая мерцание данных. Дополнительные методы trigger и redraw заставляют инициализированный экземпляр FooTable обновляться при изменении данных.

Эта директива сохраняет пользовательский опыт - любая сортировка, фильтрация или разбиение на страницы FooTable остается на месте - при загрузке данных без проблем всякий раз, когда она обновляется.

Ответ 2

Я наткнулся на тот же вопрос. После окончательного написания собственного решения для получения таблицы со скрытыми столбцами мне удалось решить вашу проблему (предполагая, что вы используете ng-repeat для построения вашей таблицы).

HTML:

<div ng-init="friends =     [{name:'data11', phone:'data12'},
                         {name:'data21', phone:'data22'},
                         {name:'data31', phone:'data32'},
                         {name:'data41', phone:'data42'},
                         {name:'data51', phone:'data52'}]"></div>

Search: <input ng-model="searchText">
<table id="searchTextResults" class="footable">
<thead>
  <tr><th>Column1</th><th>Column2</th><th data-hide="phone">Column3</th><th data-hide='phone'>Column4</th><th data-hide='phone'>Column5</th></tr>
</thead>

<tbody>
  <tr ng-repeat="friend in friends | filter:searchText" my-directive>
    <td>{{friend.name}}</td>
    <td>{{friend.phone}}</td>
    <td>{{friend.phone}}</td>
    <td>{{friend.phone}}</td>
    <td>{{friend.phone}}</td>
  </tr>
</tbody>
</table>

Контроллер:

.directive('myDirective', function(){
  return function(scope, element)
  {

    if(scope.$last && !$('.footable').hasClass('footable-loaded')) {
            $('.footable').footable();
    }

    var footableObject = $('.footable').data('footable');
    if (footableObject  !== undefined) {
            footableObject.appendRow($(element));
    }

  };})

Надеюсь, что это поможет.

Ответ 3

На всякий случай, когда кто-то случайно столкнется с этим в будущем, существует директива angular, доступная для FooTable здесь: https://github.com/ziscloud/angular-footable.