Ошибка:
Error: Template parse errors: Parser Error: Bindings cannot contain assignments at....
line:
<div>Closed: {{blah}}.find()
...
HTML:
<div fxLayout = "row" fxLayoutAlign = "start center" fxLayoutGap = "4px">
<div>Total: {{(issuesData$ | async)?.length}}</div>
<div>Closed: {{(issuesData$ | async)?.filter(data => {data.closedOn}).length}}</div>
</div>
Мне любопытно, можно ли использовать поиск/фильтр, не сталкиваясь с ошибкой синтаксического анализа шаблона, когда поиск/фильтр вызывается для коллекции в операторе интерполяции.
Обновлено:Angular 2 - привязки не могут содержать назначения — у меня это не работает, потому что я передаю компоненту Observable. OnInit я присваиваю переменную данных @Input наблюдаемому объекту IssueData$. Использование чего-то вроде {{getCount()}} в интерполяции приводит к отсутствию данных. Я попытался реализовать это следующим образом:
УГЛОВОЙ:
@Input()
data;
ngOnInit() {
this.issuesData$ = this.data;
}
getCount(){
this.issuesData$.subscribe(data => {
return data.length;
})
}
HTML:
<div>Total: {{getCount()}}</div>
Но подписаться не на что, когда в интерполяции вызывается getCount()
и это тоже не работает {{(getCount() | async}}
@mbojko Пожалуйста, посмотрите мое редактирование вопроса, спасибо.
Почему бы не использовать map
вместо этого? Это был бы более чистый способ сделать это ИМО.
Вы должны подписаться на свой Observable и вместо этого вручную назначать нужные переменные, просто чтобы уменьшить сложность кода вашего шаблона.
@Input()
data;
total: number;
closed: number;
ngOnInit() {
this.issuesData$ = this.data;
this.issuesData$.subscribe(next => {
this.total = next.length;
this.closed = next.filter(x => x.closedOn).length;
}
}
Затем просто используйте переменные total
и closed
в своем шаблоне.
Чтобы вызвать find
или filter
из асинхронного массива в шаблоне, определите обратный вызов в классе компонента. Например, вы можете установить метод isClosedOn
в качестве обратного вызова filter
:
<div>Closed: {{ (issuesData$ | async)?.filter(isClosedOn).length }}</div>
и определите его следующим образом в классе компонента:
public isClosedOn = data => data.closedOn;
См. этот стекблиц для демонстрации.
map
и отформатировать ответ таким образом, чтобы данные можно было легко использовать в компоненте/шаблоне.subscribe
, хотя вы можете присвоить значение.find
возвращает одно совпадение, filter
возвращает массив. Вы хотели использовать filter
, если хотите увидеть общее количество совпадений, используя length
shareReplay
, наблюдаемый будет разрешен один раз, поэтому его можно будет вызывать несколько раз, используя либо async
каналы, либо subscribe
без дополнительных затрат, если он делает что-то с внешними ресурсами, например, делает http-запрос.Шаблон.html
<div>Total: {{(issuesData$ | async)?.length}}</div>
<div>Closed: {{(issuesData$ | async)?.closedOnLength}}</div>
ВашКомпонент.ts
import { Observable } from 'rxjs';
import { map, shareReplay } from 'rxjs/operators';
@Input()
data: Observable<{closedOn:any}[]>;
issuesData$: Observable<{length: number, closedOnLength: number}>;
ngOnInit() {
this.issuesData$ = this.data.pipe(map((_) => {
return {
length: _.length,
closedOnLength: _.filter(d => d.closedOn).length
};
}), shareReplay());
}
count: number;
readCount() {
// you can't return data in a subscribe callback, it is asynchronous
// you can assign a value though
this.issuesData$.subscribe(_ => this.count = _.length);
}
Мне нравятся ваши ответы и ответы ConnorsFan. Я довольно быстро понял свою ошибку с подпиской/возвратом и в итоге выполнил задание, которое в конечном итоге превратилось в подробную версию ответа Nothematic.
Возможный дубликат Angular 2 - привязки не могут содержать назначения