05.10.2014, 10:41
|
|
Аспирант
|
|
Регистрация: 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");
});
Но это эффекта не имеет, селект по прежнему остаётся пустым.
Подскажите как правильно решить данный вопрос?
Как-то организовать отложенное применение декорирующей директивы или обновление плагина?
|
|
05.10.2014, 12:18
|
sinistral
|
|
Регистрация: 28.03.2011
Сообщений: 5,418
|
|
можно демку на plunker ?
|
|
05.10.2014, 13:31
|
|
junior
|
|
Регистрация: 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));
}
};
})
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
|
|
06.10.2014, 11:13
|
|
Аспирант
|
|
Регистрация: 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.
|
|
06.10.2014, 12:28
|
|
Аспирант
|
|
Регистрация: 15.06.2008
Сообщений: 47
|
|
Ан, нет, снова я поспешил. Всё равно через раз работает. Поясните, пожалуйста, что нужно сделать, возможно я смогу подпилить?
По всей вероятности не вызывается событие когда надо. Если модель меняется уже после загрузки данных, до да, всё происходит как нужно. Но после первоначальной загрузки страницы список пуст.
Последний раз редактировалось Sufir, 06.10.2014 в 12:33.
|
|
06.10.2014, 14:00
|
|
Аспирант
|
|
Регистрация: 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.
|
|
06.10.2014, 16:21
|
|
junior
|
|
Регистрация: 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.
|
|
07.10.2014, 12:02
|
|
Аспирант
|
|
Регистрация: 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.
|
|
|
|