Comments 22
Безусловно, однако я не уверен что у меня есть устойчивый к хабраеффекту хостинг
Дык, чего там вставлять, вы грид никогда не видели? Столбцы, строки, циферки внизу для пейджинга. Как захочешь, так он и будет выглядеть, в статье описаны только внутренности.
поверьте, лучше один раз увидеть чем десять раз услышать прочитать
Картинку добавил. Думаю над размещением где-то в паблике примера или портированием на jsfiddle.
Клева! Хорошая статья. Сам как раз сегодня написал похожий грид с использованием Knockoutjs. И в процессе написания возник вот какой вопрос. Можно ли в шаблоне как-то докопаться до модели представления, если она не является глобальным объектом?

Например у нас есть такой шаблончик:

<table class="ColumnTable">
    
    <tr data-bind='template: { name: "GridColumnTable", foreach: Columns }' ></tr>

</table>

<script type="text/html" id="GridColumnTable">       
    <td>
        <span data-bind="text: HeaderName, css:{SortedColumn:Sort()!='none'}, click: function(event){ viewModels.TotalCallsGrid.ChangeSort(this);  } "></span>
        <span data-bind="style :{ display: (Sort()!='up')?'none':'' } " class="ColumnSortArrow">↑ </span>
        <span data-bind="style :{ display: (Sort()!='down')?'none':'' } " class="ColumnSortArrow">↓ </span>      
    </td>
</script>



Как видно при клике по столбцу, у меня вызывается обработчик function(event){ viewModels.TotalCallsGrid.ChangeSort(this);} и в нем обращение к модели идет через глобальный объект viewModel, который я ввел в качестве костыля. Как просто получить доступ к текущей модели?

ЗЫ Кто-нибудь помогите разработчиком хабра написать нормальный редактор.
Можно:

data-bind='template: { name: «GridColumnTable», foreach: Columns, templateOptions: { ViewModelParent: $data } }'

и

click: function(event){ $item.ViewModelParent.TotalCallsGrid.ChangeSort(this); }

примерно так.
Выложить-то можно, но в его нынешнем виде — это малополезно. Но я обещаю обдумать эту перспективу.
Хостинг и правда упал, а пример с html js css можно было бы выложить сюда jsfiddle и вставить прямо в статью.
Тоже недавно смотрел фреймворк, на мой взгляд там пока слишком сложно обрабатываются кастомные контролы, вроде слайдеров. А если использовать стандартные, да все хорошо выходит.
В своей предыдущей статье я довольно много залил на jsfiddle. Но я не нашёл как вставлять в пост с фиддла вставки.

Касательно сегодняшней статьи, я не смог симулировать реальный backend с помощью ихнего echo. Хотя можно по колдовать и получится, но тогда пример уже получится не чистым.

А на счёт не нативных контролов, то да, вы правы. Есть 2 пути решения этой проблемы:
  • кастомный биндинг, который будет самостоятельно инициализировать кастомные контролы и управлять ими
  • кастомный биндинг, который будет управлять уже проиницилизированными кастомными контролами.


Решение надо принимать на уровне проекта и потом следовать ему. В любом случае, вам надо будет один раз описать все кастомные биндинги (slider, datapicker, accordion, button) и потом просто их использовать.

Вот один из примеров: jsfiddle.net/rniemeyer/Rn9tg/
А можно поподробнее, как избавиться от двойной перезагрузки данных при изменении условий фильтрации???
Как вы меня порадовали своим комментарием. Значит кто-то внимательно проработал статью. На самом деле я элементарно протупил, когда делал пример. Я уже в последний момент подумал, что надо сбрасывать номер страницы в единицу. И быстренько прикрутил. Потом уже, при написании статьи, когда описывал шаги, увидел что-то будет идти 2 запроса и даже не пытался решить эту проблему, мне показалось всё сложнее чем есть на самом деле.

По сути, наш главный dependentObservable должен следить только за изменением номера страницы. А номер страницы может меняться по двум причинам: пользователь перешёл на другую страницу или изменил условия фильтрации. Осталось только получить значение всех параметров при этом не получая их значения через функцию-getter. Для этого у нас есть ko.utils.unwrapObservable(). Он вернёт нам plain object и при это dependentObservable не будет изменяться при изменении параметров фильтрации. Иными словами надо заменить
var data = ko.toJS(this.filterParams);

на
var data = ko.utils.unwrapObservable(this.filterParams);


Код в статье поправил
угу, ясно. только тоогда нужно учесть момент, что если мы были на первой странице и изменили параметры фильтрации, то наш основной dependentObservable по идее не будет вызван(номер страницы то не изменился), а значит перегрузку данных нужно и вспомогательном dependentObservable тоже делать. примерно так:

ko.dependentObservable(function () {
var data = ko.toJS(this.filterParams);
// Reset page number when any filtration parameters change
if (this.paging.PageNumber() == 1) {
// получаем данные через ajax
} else {
this.paging.PageNumber(1);
}
}, this);

Вы отчасти правы. Я имел те же самые сомнения. Но они разбились о суровую правду реальности. Как-ни странно, но мой пример работает без этой проверки. На самом деле я до конца не разобрался, почему он работает, ведь не должен :-) Как разберусь, обязательно напишу
На самом деле я тоже имел те же самые сомнения. Но они разбились о суровую правду жизни. Как-ни странно, но мой пример работает без этой проверки. На самом деле я до конца не разобрался, почему он работает, ведь не должен :-) Как разберусь, обязательно напишу
не помешали бы более подробные комментарии к коду, но все равно спасибо!
Предполагается, что читатель уже немного знаком с Knockout'ом. Если есть неясности — задавайте. Я рассказывал о Knockout'е на .NET Saturday в Днепропетровске. Можно посмотреть видео: vimeo.com/27047951. Где-то с 20той минуты идёт демонстрация создания простенького приложения. До этого просто введение в MVVM.

Если есть конкретные вопросы по коду, с удовольствием отвечу.
Only those users with full accounts are able to leave comments. Log in, please.