Нелегко с этим. Я новичок в работе с RxJs Observables, поэтому мне нужно руководствоваться.Настроить наблюдаемое, чтобы вернуть все предыдущие значения в виде массива при нажатии нового значения?
Я пытаюсь создать Наблюдаемый поток ведения журнала, который выполняет две вещи.
- Всякий раз, когда новая строка/значение записывается в файл журнала, нажмите это новое значение в поток.
- Начните предварительно заполненные значения из файла журнала.
Я выполнил оба вышеуказанных критерия. Теперь проблема заключается в использовании * ngFor.
* ngFor требует массив из наблюдаемого, поэтому он может делать сравнение с добавлением/удалением (мое лучшее предположение). Но мой наблюдаемый возвращает только массив последнего элемента, проталкиваемого.
//logviewer.page.ts constructor()
this.logs = Subject.create();
this.logs$ = this.logs.asObservable()
.startWith("logs\\error.log")
.flatMap((fileName: string) => {
//start by reading the existing log files as a string
return this.$localStorageService.readAsStringAsync(fileName);
})
.map((contents: string) => {
//this part splits up the log file line-by-line into an log entry
let logs = contents.split(/\r\n|\r|\n/).filter(n => n.length > 0);
logs.forEach((s, ix, parent) => {
let x = JSON.parse(s);
parent[ix] = { timestamp: new Date(parseFloat(x[0])), message: x[1] };
})
return logs; //an array of objects { timestamp, message }
})
//merge the existing application log stream
//throughout the application we log errors, info, etc
//if a new entry is made it will appear here
.merge(this.$loggerService.applicationLog$.map((x) => {
//return an array with one object { timestamp, message }
return [{ timestamp: new Date(parseFloat(x[0])), message: x[1] }];
}))
Теперь мой шаблон очень прост, на данный момент.
//logviewer.template.ts
<div *ngFor="let entry of logs$ | async">
{{entry|json}}
</div>
Теперь, чтобы проверить это, у меня есть кнопка, чтобы добавить запись
//logviewer.page.ts
addEntry() {
this.$loggerService.error("this is a test");
}
//LoggerService.service.ts
private applicationLog: ReplaySubject<any[]>;
get applicationLog$(): Observable<any[]> {
return this.applicationLog.asObservable();
}
error(...args) {
let data = [Date.now().toString()].concat(args.map<string>((n, ix) => { return toString(n); }));
// ... write to file
// fire the subject
this.applicationLog.next(data);
}
Теперь, когда я нажимаю addEntry
, сантехника все работает, а значение увольняют по наблюдаемой последовательности правильно. Но my * ngFor только обновления с одним значением. Он не сохраняет историю всех предыдущих записей журнала. Только последний массив вернулся, что имеет смысл.
Как заставить мою наблюдаемую последовательность всегда возвращать массив всех значений. Я могу заставить его возвращать одну запись за раз, но мне нужна полная история, чтобы удовлетворить * ngFor
У меня было отсутствие понимания * ngFor и асинхронной трубы. Я думал, что он подписывается на наблюдаемый и автоматически добавляет новые записи в ngFor, но это не так.
Вау, спасибо так много. – Matt