Ваш isVisible
pendentObservable создал зависимость от себя и рекурсивно пытается оценить себя на основе этой строки:
if (!visible) {
viewModel.users.remove(this);
}
Итак, это создает зависимость от viewModel.users, так как remove должен получить доступ к базовому массиву observableArray, чтобы удалить пользователя. В момент изменения массива подписчики уведомляются, и один из подписчиков будет сам.
Обычно лучше не менять состояние каких-либо наблюдаемых в зависимой наблюдаемой. вы можете вручную подписаться на изменения зависимого объекта и вносить в него изменения (при условии, что зависимый объект не зависит от того, что вы меняете).
Однако в этом случае я бы, вероятно, вместо этого создал бы зависимый объект наблюдения на уровне viewModel, который называется что-то вроде filteredUsers
. Затем верните версию отфильтрованного массива пользователей.
Это может выглядеть так:
viewModel.filteredUsers = ko.dependentObservable(function() {
var selected = viewModel.selectedKeyword();
//if nothing is selected, then return an empty array
return !selected ? [] : ko.utils.arrayFilter(this.users(), function(user) {
//otherwise, filter on keywords. Stop on first match.
return ko.utils.arrayFirst(user.keywords(), function(keyword) {
return keyword === selected;
}) != null; //doesn't have to be a boolean, but just trying to be clear in sample
});
}, viewModel);
Вам также не нужно указывать грязный флаг, так как зависимые наблюдательные объекты будут повторно запускаться при изменении любых наблюдаемых объектов, к которым у них есть доступ. Таким образом, поскольку он обращается к selectedKeyword, он будет переоцениваться при каждом изменении selectedKeyword.
http://jsfiddle.net/rniemeyer/mD8SK/
Надеюсь, я правильно понял ваш сценарий.