Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 05.10.2014, 10:41
Аватар для Sufir
Аспирант
Отправить личное сообщение для Sufir Посмотреть профиль Найти все сообщения от Sufir
 
Регистрация: 15.06.2008
Сообщений: 47

AngularJS и плагин jQuery UI
В общем, есть на странице селект, по которому фильтруется вывод основных данных. Он должен быть декорирован Selectmenu.
Я набросал простейшую директиву:
function($scope, element, attrs, controller) {

        // Получаю опции из атрибута
        var options = $scope.$eval(attrs['selector']);

        angular.extend(options, {
            // Без этого модель привязанная к селекту не обновляется
            change: function(event, object) {
                element.trigger('change');
            }
        });

        // Применяю плагин
        $(element).selectmenu(options);

}


Тут всё хорошо, всё работает. Но т.к. приложение RESTfull (это мой первый опыт) данные для селекта должны подгружаться динамически. И в итоге получается, что когда данные пришли и оригинальный селект заполнился - Selectmenu уже применён и пустой.
Причём получается от случая к случаю: обновляешь страницу, если данные пришли быстро - то и в декорированном селекте появились, если нет то он пустой (оригинальный, который скрыт в порядке).

Я пробовал вызывать .selectmenu("refresh"); после загрузки данных:
$scope.staffList = Staff.query({fOnlyAuthors: 1}, function(){
        // console.log(jQuery(".selector", element).length)
        jQuery(".selector", element).selectmenu("refresh");
});

Но это эффекта не имеет, селект по прежнему остаётся пустым.

Подскажите как правильно решить данный вопрос?
Как-то организовать отложенное применение декорирующей директивы или обновление плагина?
Ответить с цитированием
  #2 (permalink)  
Старый 05.10.2014, 12:18
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

можно демку на plunker ?
Ответить с цитированием
  #3 (permalink)  
Старый 05.10.2014, 13:31
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

делай по аналогии
/*
 ОБертка для jquery-chosen
 */
.directive('ngChosen', function() {
    return {
        replace: true,
        link: function(scope, element, attributes) {
            var params = scope.$eval(attributes.ngChosen) || {};

            element.chosen(params);

            function handler() {
                element.trigger('chosen:updated');
            }

            element.bind('$destroy', scope.$watch(attributes.ngModel, handler));
            element.bind('$destroy', scope.$watch(attributes.ngDisabled, handler));
        }
    };
})
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
  #4 (permalink)  
Старый 06.10.2014, 11:13
Аватар для Sufir
Аспирант
Отправить личное сообщение для Sufir Посмотреть профиль Найти все сообщения от Sufir
 
Регистрация: 15.06.2008
Сообщений: 47

Сообщение от nerv_ Посмотреть сообщение
делай по аналогии
/*
 ОБертка для jquery-chosen
 */
.directive('ngChosen', function() {
    return {
        replace: true,
        link: function(scope, element, attributes) {
            /.../
        }
    };
})
Такой вариант так же не имеет эффекта, список почему-то ни в какую не обновляется. Хотя обработчик успешно запускается.

Что самое интересное, получается, если не трогать селект до того момента как получены данные - список формируется. Специально для проверки ставил таймаут, что б подольше получать данные, и до трёх-четырёх секунд грузятся, но появляются. А если сразу после загрузки страницы по декорированному селекту кликнуть, то он так и остаётся пустым в дальнейшем.

// UPD: //
Извиняюсь, тупанул, не тот триггер вызывал. Да, действительно сработало! Но мне не совсем понятно. Мы биндим триггер обновляющий список на событие $destroy. Почему именно на него? Что-то посмотрел в документацию, и не понял.
Не могли бы вы вкратце объяснить, что происходит в данной ситуации?

Последний раз редактировалось Sufir, 06.10.2014 в 12:04.
Ответить с цитированием
  #5 (permalink)  
Старый 06.10.2014, 12:28
Аватар для Sufir
Аспирант
Отправить личное сообщение для Sufir Посмотреть профиль Найти все сообщения от Sufir
 
Регистрация: 15.06.2008
Сообщений: 47

Ан, нет, снова я поспешил. Всё равно через раз работает. Поясните, пожалуйста, что нужно сделать, возможно я смогу подпилить?

По всей вероятности не вызывается событие когда надо. Если модель меняется уже после загрузки данных, до да, всё происходит как нужно. Но после первоначальной загрузки страницы список пуст.

Последний раз редактировалось Sufir, 06.10.2014 в 12:33.
Ответить с цитированием
  #6 (permalink)  
Старый 06.10.2014, 14:00
Аватар для Sufir
Аспирант
Отправить личное сообщение для Sufir Посмотреть профиль Найти все сообщения от Sufir
 
Регистрация: 15.06.2008
Сообщений: 47

$scope.staffList = Staff.query({fOnlyAuthors: 1}, function(){
        jQuery(".selector", element).selectmenu("destroy").selectmenu();
});

Вот так работает, т.е. директиву можно убрать вообще. Но вероятно это не правильно. Вообще не понятно почему в этом месте срабатывают корректно любые методы плагина (destroy, disable, open) только не refresh.

Последний раз редактировалось Sufir, 06.10.2014 в 17:11.
Ответить с цитированием
  #7 (permalink)  
Старый 06.10.2014, 16:21
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

html
<select ng-model="app.model.property" ng-options="item.id as item.title for item in app.dictionaries.categories" ng-chosen=""></select>


js
/**
 * jQuery-chosen wrapper
 * @see [url]http://harvesthq.github.io/chosen/[/url]
 */
.directive('ngChosen', [
    function() {
        return {
            link: function(scope, element, attributes) {
                var options = scope.$eval(attributes.ngChosen);
                var settings = angular.extend({}, options);
    
                element.chosen(settings);
    
                element.bind('$destroy', scope.$watch(attributes.ngModel, handler));
                element.bind('$destroy', scope.$watch(attributes.ngDisabled, handler));
                element.bind('$destroy', destructor);
    
                // -----------------------
    
                function handler() {
                    element.trigger('chosen:updated');
                }
    
                function destructor() {
                    element.chosen('destroy');
                }
            }
        };
    }
])
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук

Последний раз редактировалось nerv_, 06.10.2014 в 16:39.
Ответить с цитированием
  #8 (permalink)  
Старый 07.10.2014, 12:02
Аватар для Sufir
Аспирант
Отправить личное сообщение для Sufir Посмотреть профиль Найти все сообщения от Sufir
 
Регистрация: 15.06.2008
Сообщений: 47

Мой окончательный вариант:
directive('selector', function() {
    return {
        restrict: 'A',
        replace: true,
        //require: '?ngModel',
        link: function($scope, element, attributes, controller) {

            var options = $scope.$eval(attributes['selector']) || {};

            angular.extend(options, {
                change: function(event, object) {
                    element.trigger('change');
                }
            });

            element.selectmenu(options);

            element.bind('$destroy', $scope.$watch(attributes.ngModel, handler));
            element.bind('$destroy', $scope.$watch(attributes.ngDisabled, handler));
            element.bind('refresh-me', refreshMe);

            function handler() {
                element.selectmenu("refresh");
            }

            function refreshMe() {
                element
                    .selectmenu("destroy")
                    .selectmenu(options);
            }

        }
    };
});

<select class="selector"
     ng-model="selectedStaff"
     ng-options="(staff.surname + ' ' + staff.name) for staff in staffList"
     data-selector="{icons: {button: 'ui-icon-list'}}">

$scope.staffList = Staff.query({}, function(){
    $(".selector", element).trigger('refresh-me');
}


Не уверен, что в полной мере правильно с точки зрения Angular, но задачу решает.
nerv_, спасибо за помощь и наводки.

Последний раз редактировалось Sufir, 07.10.2014 в 12:10.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Существует ли плагин на подобие fancybox без использования jquery protexon jQuery 1 01.06.2014 19:33
Ни один скрипт и плагин не видит Jquery razorg1991 jQuery 5 30.03.2014 14:51
плагин jquery ajax upload Karabella jQuery 0 06.06.2013 21:25
Плагин jQuery form. Добавляю форму js'ом Physicist jQuery 3 21.07.2011 17:46
syncTranslate jQuery плагин Snowcore Ваши сайты и скрипты 0 20.10.2009 19:00