2014-01-21 4 views
7

У меня есть массив объектов, которые подключены к наблюдаемому массиву нокаута. Мне нужно было применить сортировку к этим массивам, и я столкнулся с некоторым поведением, которое немного запутывает.Нокаут Наблюдаемый массив с сортировкой и привязкой привязки Foreach

Моя первая попытка заключалась в применении сортировки в привязке данных foreach.
http://jsfiddle.net/wnfXV/

<ul data-bind="foreach: people.sort(function(l,r) { return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1)})">

Это выполняет правильную сортировку, но я теряю способность динамически добавлять/удалять элементы из массива и есть обновление DOM.

Если я добавляю набор скобок для доступа к базовому массиву JavaScript, все работает нормально.

<ul data-bind="foreach: people().sort(function(l,r) { return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1)})">

Основываясь на некоторых SO ответов, которые я нашел, я в конечном итоге создание вычисляемого наблюдаемой для отсортированного массива. http://jsfiddle.net/wnfXV/2/

self.sortedPeople = ko.computed(function() { 
    return self.people().sort(function(l,r) { 
     return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1); 
    }); 
}); 

Это также работает. И мне даже не нужно привязывать данные к вычисленному наблюдаемому, так как он выполняется немедленно. Я могу соответствующим образом удалять и удалять элементы массива и обновления DOM.

Однако, если изменить код:

self.sortedPeople = ko.computed(function() { 
    return self.people.sort(function(l,r) { 
     return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1); 
    }); 
}); 

Теперь я могу выдвинуть элементы в массив и обновления DOM, но данные не отсортированы.

Я думаю, что эти различия связаны с отслеживанием зависимостей нокаута и разницей между работой над наблюдаемым массивом и встроенным массивом JavaScript под ним, но мне сложно понять, почему поведение меняется. Я могу заставить его работать, но мне также интересно, что считается лучшей практикой.

Спасибо за любую помощь. :)

ответ

1

В вашей JS Fiddle это потому, что ваш foreach привязан к людям ... не сортировать людей.

Причина его сортировки в первый раз заключается в том, что вычисляемые прогоны раз ... но не подписываются.

Однако вычисленный результат заканчивается, когда вы используете скобку из-за некоторой подписки на базовый массив.

Edit:

При использовании скобки, вычисленный подписываются на массив, когда наблюдаемый вызываются. Когда подписанный элемент изменяется, вычисление выполняется повторно.

+0

Это может быть более ясным, если вы просто подписались на наблюдаемый массив вместо использования вычисленного. Вы в основном используете рассчитанные для подписки. http://jsfiddle.net/N9sGY/ – LameCoder

+0

Да, это объясняет последний пример, когда элементы добавляются, но не используются. Благодарю. любые идеи, почему функция push/remove не работает в первой скрипке или почему добавление скобок исправляет ее? – ecozoic

+0

В первой скрипке это в основном то же самое. Поскольку вы не используете скобки, подписка не выполняется. Выполнение people.sort в основном сокращает механизм, который подписывается на изменения. – LameCoder

2

Проблема с использованием своего рода во взглядах на самом деле не рекомендуется, так как KO с этим подходом observableArray.sort не устанавливает зависимость от массива, так что связывание не будет обновляться.

Так что, если вы хотите, чтобы сделать его работу можно использовать

items.slice(0).sort() 

для более детального взгляда на
https://github.com/knockout/knockout/issues/1380

Fiddle: http://jsfiddle.net/mbest/6dmAn/