Вы ищете асинхронную трубу :
Асинхронный канал подписывается на Observable или Promise и возвращает
последнее значение он выпустил. Когда выдается новое значение, асинхронный
труба отмечает компонент, который будет проверен на наличие изменений. Когда компонент
уничтожается, асинхронный канал отписывается автоматически, чтобы избежать
потенциальные утечки памяти.
Итак, если ваша наблюдаемая возвращает строку с изображением src, ваш рефакторинг может выглядеть следующим образом:
..img ... src="{{getUserProfilePicture(request.clientId) | async}}" ... ">
Я создал рабочий пример асинхронного канала в цикле ngFor
для справки.
Некоторые потенциальные вещи, на которые следует обратить внимание с помощью асинхронного канала: каждый раз, когда вы используете ту же самую наблюдаемую, она снова подпишется на наблюдаемую, если вы не захватите значение с использованием синтаксиса as
. Это означает следующее: если у вас есть асинхронный канал, который, например, вызывает веб-сервис, он будет вызываться несколько раз, если вы сделаете что-то вроде этого:
<!-- Async pipe subscribes once... -->
<img src="{{someHttpCall(request.clientId) | async}}"/>
<!-- Async pipe subscribes again... -->
<p>Img loaded from: {{someHttpCall(request.clientId) | async}}</p>
Если вы хотите изменить рефакторинг вышеприведенного нам синтаксиса as
, чтобы захватить вывод и избежать нескольких обращений к серверу, это выглядело бы так:
<!-- Capture our observable to prevent subsequent subscriptions.
Async pipe only subscribes once. -->
<ng-container *ngIf="someHttpCall(request.clientId) | async as imgSrc">
<img src="{{ imgSrc }}"/>
<!-- Also note we don't need the async pipe because it already subscribed
to the observable for us and we captured the value in our template -->
<p>Img loaded from: {{ imgSrc }}</p>
</ng-container>
Во всяком случае, это ловушка, в которую попадают многие новые разработчики Angular, поэтому я решил, что не введу трубу async
без хотя бы небольшого предостережения.