Не все представления клиента обновляются, когда я удаляю документы из коллекции. Почему?

Я использую Angular2-meteor, который использует Angular2 Beta 1 (на данный момент).

У меня есть простой компонент, содержащий:

  • Кнопка для добавления документа. Новый документ отображается с кнопкой для его удаления по его _id.
  • Также есть кнопка «Удалить все», которая просматривает collection.find(), удаляя каждый документ по _id.

В основном работает нормально. Вы можете добавлять документы и удалять их с помощью отдельной кнопки удаления. Когда вы «Удалить все», он удаляет их всех из базы данных. Курсор сообщает, что count() равен 0. Новый collection.find().count() сообщает 0. Но он удаляет только первый документ, который отображается в шаблоне с помощью *ngFor на странице клиент, который инициировал removeAll(). Другие документы по-прежнему отображаются в браузере. Когда вы перезагружаете страницу, она отображает правильное содержимое базы данных. Другие подключенные клиенты всегда отображают правильное содержимое коллекции. Затрагивается только клиент, который инициирует removeAll().

Шаблон, кнопка "Удалить все" и *ngFor отображение документов

<input type="button" value="Remove All" (click)="removeAll()">
<ul>
  <li *ngFor="#doc of docs">
    <input type="button" value="Remove" (click)="remove(doc._id)">
    point: x={{ doc.x }} y={{ doc.y }} _id={{ doc._id }}
  </li>
</ul>

Компонент:

@Component({
    selector: 'db-test',
    templateUrl: 'client/db-test/db-test.html',
    directives: [CORE_DIRECTIVES],
})
export class DbTestComponent{
    coll = DbTestCollection;
    docs: Mongo.Cursor<Object>;

    constructor() {
        this.docs = this.coll.find();
    }

    removeAll() {
        this.docs.forEach((d) => {
            this.coll.remove(d._id);
        });
    }

    remove(id) {
        this.coll.remove({ _id: id });
    }

    add(point: Point = {x: Math.random(), y: Math.random()}) {
        this.coll.insert(point);
    }

}

person drewlio    schedule 31.01.2016    source источник
comment
Я собираюсь убрать это и сделать заголовок вопроса более подходящим, теперь, когда я немного больше понимаю проблему.   -  person drewlio    schedule 01.02.2016


Ответы (1)


Запустите также код в removeAll, remove и add в zone

person Günter Zöchbauer    schedule 31.01.2016
comment
Я не знаю, видели ли вы редактирование внизу, Tracker.autorun() даже не нужно, так как курсор, возвращенный из this.coll.find(), будет реактивным через Meteor. Поэтому я не уверен, что вы подразумеваете под запуском их в зоне. Не могли бы вы уточнить? - person drewlio; 01.02.2016
comment
Я имею в виду, что вы должны попробовать один из них в каждом из перечисленных методов stackoverflow.com/a/34829089/217408. Вызовы coll.remove и coll.insert возвращают обещания? - person Günter Zöchbauer; 01.02.2016
comment
Курсор реактивный и по умолчанию .remove находится в зоне. Однако .remove Метеора является асинхронным и может принимать обратный вызов. Я думаю, что происходит то, что .forEach быстро пробегает по курсору, и обнаружение изменений происходит до того, как элементы будут удалены из коллекции, и это распространяется через реактивность Метеора. Из 2-го ответа в предоставленной вами ссылке можно обернуть .remove в window.setTimeout( <function>, 0). Вызывает ли это обнаружение изменений сразу после .remove? Это состояние гонки? - person drewlio; 03.02.2016
comment
Это то, что я намеревался сообщить своим ответом. Вы уже использовали zone.run(...) в конструкторе до того, как отредактировали свой вопрос. Мой ответ был об использовании его и в других методах. Я не знаю ни Meteor, ни то, что возвращают вызовы, ни какие побочные эффекты они имеют. Я могу получить решение только из того, что показывает ваш вопрос. - person Günter Zöchbauer; 03.02.2016
comment
для других, следующих за этим, это обсуждается в github.com/angular/angular/issues/6005< /а> - person drewlio; 03.02.2016