signals - Difference between changing input of Angular component inside and outside a component (+animations) - Stack Overflow

I made an accordion component (angular18) with lazy loading of it's body content and smooth animat

I made an accordion component (angular18) with lazy loading of it's body content and smooth animation of opening and closing. So it works pretty well when i toggle it from inside (by clicking on header), but when i toggle it from outside - it doesn't open smoothly (but closes smoothly).

Here's the stackblitz:

What's the point of this behavior? i'm quite new to Angular animations..

tried to replace model with input - same thing. Css animations with maxheight are not good enough because of different content sizes.

upd. added squares to ensure than animations works there - they do.

I made an accordion component (angular18) with lazy loading of it's body content and smooth animation of opening and closing. So it works pretty well when i toggle it from inside (by clicking on header), but when i toggle it from outside - it doesn't open smoothly (but closes smoothly).

Here's the stackblitz: https://stackblitz/edit/stackblitz-starters-rjsmkv

What's the point of this behavior? i'm quite new to Angular animations..

tried to replace model with input - same thing. Css animations with maxheight are not good enough because of different content sizes.

upd. added squares to ensure than animations works there - they do.

Share Improve this question edited Nov 16, 2024 at 17:45 argentum4k asked Nov 16, 2024 at 14:35 argentum4kargentum4k 331 silver badge5 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I think the problem is due to mixing of signal and observable updates. Where the signal is updated first followed by the observable being updated later.

The scenario is there is no content inside the accordion and the signal is updated, then the animation has already started. At a later point of time the observable delayedIsOpen is updated by that time the animation is midway or even over. This causes the jerk.

I have noticed that using both the sources as observables, solves the issue.

So we can create another observable isOpenDelayed = toObservable(this.isOpen); just to fix the timing issue, then use this to trigger the animation.

<div
  class="main-content"
  [@content]="
    (isOpenDelayed | async)
      ? { value: 'visible', params: { transitionParams } }
      : { value: 'hidden', params: { transitionParams } }
  "
>
  @if (delayedIsOpen | async) {
  <ng-container *ngTemplateOutlet="accordionBodyRef" />
  }
</div>

Full Code:

HTML:

<div
  class="test"
  [@sqare]="
    isOpen()
      ? { value: 'red', params: { transitionParams } }
      : { value: 'blue', params: { transitionParams } }
  "
>
  isOpen
</div>
<p></p>
<div
  class="test"
  [@sqare]="
    (delayedIsOpen | async)
      ? { value: 'red', params: { transitionParams } }
      : { value: 'blue', params: { transitionParams } }
  "
>
  delayedIsOpen
</div>

<p></p>

<div
  class="accordion"
  [ngStyle]="{ '--transiton-time': transitionTime + 'ms' }"
>
  <div class="accordion-head">
    <div class="top-side top-side_left" (click)="toggle()">
      <ng-content select="[topLeft]" />
    </div>
  </div>
  <div
    class="main-content"
    [@content]="
      (isOpenDelayed | async)
        ? { value: 'visible', params: { transitionParams } }
        : { value: 'hidden', params: { transitionParams } }
    "
  >
    @if (delayedIsOpen | async) {
    <ng-container *ngTemplateOutlet="accordionBodyRef" />
    }
  </div>
</div>

TS:

import {
  animate,
  state,
  style,
  transition,
  trigger,
} from '@angular/animations';
import {
  ChangeDetectionStrategy,
  Component,
  input,
  model,
  ContentChild,
  TemplateRef,
} from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
import { delay, of, switchMap } from 'rxjs';

@Component({
  selector: 'accordion',
  templateUrl: './accordionponent.html',
  styleUrl: './accordionponent.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
  animations: [
    trigger('content', [
      state(
        'hidden',
        style({
          height: '0',
          visibility: 'hidden',
        })
      ),
      state(
        'visible',
        style({
          height: '*',
          visibility: 'visible',
        })
      ),
      transition('visible <=> hidden', [animate('{{transitionParams}}')]),
      transition('void => *', animate(0)),
    ]),
    trigger('sqare', [
      state(
        'red',
        style({
          background: 'red',
        })
      ),
      state(
        'blue',
        style({
          background: 'blue',
        })
      ),
      transition('red <=> blue', [animate('{{transitionParams}}')]),
      transition('void => *', animate(0)),
    ]),
  ],
})
export class AccordionComponent {
  isOpen = model<boolean>(false);

  transitionTime = 500;
  transitionParams = `${this.transitionTime}ms linear`;

  delayedIsOpen = toObservable(this.isOpen).pipe(
    switchMap((open) =>
      open ? of(open) : of(open).pipe(delay(this.transitionTime))
    )
  );

  isOpenDelayed = toObservable(this.isOpen);

  @ContentChild('accordionBody', { read: TemplateRef })
  accordionBodyRef: TemplateRef<unknown> | null = null;

  toggle(): void {
    this.isOpen.update((value) => !value);
  }
}

Stackblitz Demo

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745656552a4638575.html

相关推荐

  • 长读长测序揭示结直肠癌异常可变剪接图谱与新型治疗靶点

    徐州医科大学肿瘤研究所董东郑骏年教授团队在Genome Medicine杂志发表题为“Long-read sequencing reveals the landscape of aberrant alternative splicing

    57分钟前
    00
  • Prometheus配置docker采集器

    Prometheus 配置 Docker 采集器Prometheus 是一个开源的监控系统和时间序列数据库,广泛用于容器化环境中。通过监控 Docker 容器,用户可以实时获取服务性能、资源使用情况等信息。本文将介绍如何为 Docker 容

    51分钟前
    00
  • ascend pytorch 踩坑.

    在910b上安装pytorch 和 pytorch_npu, 因为后续准备装vllm, 所以torch_npu是特殊的版本.代码语言:shell复制pip install torch==2.5.1 --extra-index pip in

    49分钟前
    00
  • 开源在线考试系统

    看到调问已经开始扩展在线考试的场景,试了一下,发现在线考试的基本能力都已经支持了。主要是考试中的各种计分功能,包括对每道题的选项设置分值计算、考试时间限制等,和官方了解了一下,考试中的其他各项能力也在逐步完善,有需求可以随时

    48分钟前
    00
  • Power BI 无公式实现帕累托图表

    帕累托分析(Pareto Analysis),也被称为8020法则、关键少数法则,是一种常用的管理工具,用于识别和处理影响业务的主要因素。看到李伟坚老师在Excel使用Vega实现了花式帕累托(参考:Excel 零公式实现高级帕累托图表)

    46分钟前
    00
  • Go 语言 Mock 实践

    Mock 是软件测试中的一项关键技术,尤其在单元测试领域,可谓是“顶梁柱”般的存在,几乎不可或缺。它通过模拟真实对象的行为,使我们能在不依赖外部系统的情况下,专注测试代码的核心逻辑。对于测试开发、自动化测试,乃至性能测试中的某些场景,合理使

    45分钟前
    00
  • MongoDB “升级项目” 大型连续剧(2)

    上期写的是非必要不升级,想到这个事情,有一些事情的仔细琢磨琢磨,为什么数据库升级的事情在很多公司都是一个困扰,从一个技术人的观点,升级是一件好事,功能提升了,性能提升了,开发效率和一些数据库使用的痛点也被解决了,为什么就不愿意升级呢?如果只

    41分钟前
    00
  • CUT&amp;amp;Tag 数据处理和分析教程(7)

    过滤某些项目可能需要对比对质量分数进行更严格的过滤。本文细讨论了bowtie如何分配质量分数,并举例说明。MAPQ(x) = -10 * log10log10(P(x is mapped wrongly)) = -10 * log10(p)

    40分钟前
    10
  • 什么是docker?它是如何工作的?

    想象一个场景,你要部署一个服务,然后它对环境有很多依赖,不同的操作系统又是不同的需求,而且还可能遇到有些源不能使用,又得一番折腾,折腾完上线后,假设要在新的环境再来一套,又得再来一遍。那么有没有什么办法可以解决呢?有办法,docker就是干

    36分钟前
    00
  • module &#x27;torch.

    踩坑Ascend, 安装 pytorch 2.5.1 和 pytorch_npu 2.5.1, import torch 报错.执行 python -c "import torch;import torch_npu;"时

    32分钟前
    10
  • 人工智能与ai有什么区别

    一、引言:概念之辨的必要性在科技浪潮席卷全球的当下,人工智能(Artificial Intelligence,简称AI)已成为人们耳熟能详的词汇。然而,当我们深入探讨时,会发现“人工智能”与“AI”这两个表述在语义和使用场景上存在微妙差异。

    24分钟前
    00
  • Nat. Mater.

    大家好,今天给大家分享一篇近期发表在Nat. Mater.上的研究进展,题为:De novo design of self-assembling peptides with antimicrobial activity guided

    21分钟前
    00
  • 子网掩码是怎么“掩”的?用积木教你彻底搞懂!

    子网掩码是怎么“掩”的?用积木教你彻底搞懂!前言肝文不易,点个免费的赞和关注,有错误的地方请指出,看个人主页有惊喜。作者:神的孩子都在歌唱你是不是也曾被“子网掩码”这个术语搞得晕头转向?明明是学网络的第一步,却像是打开了数学世界的大门:2

    16分钟前
    00
  • 雨晨 26200.5516 Windows 11 IoT 企业版 LTSC 2024 轻装版

    简述&#xff1a;以下为YCDISM (雨晨作品自2025年03月25日起通用介绍&#xff0c;若无重大更改不再额外敖述) 全程由最新YCDISM2025脱机装载26100.1742_zh-cn_windows_11_

    14分钟前
    00
  • ​2025 轻松部署 Odoo 18 社区版

    随着 Odoo 18 社区版的发布,越来越多的企业希望借助这款开源 ERP 系统实现数字化转型。本文将深入解析传统部署方式的底层逻辑,并揭示如何通过自动化工具实现零门槛快速部署。一、手工部署 Odoo 18 技术全解 Docker 环境搭建

    13分钟前
    00
  • 用Xshell8配置密钥登陆

    1.首先在服务端查看root.sshauthorized_keys是否存在,这是存储公钥的文件,若不存在需新建此文件 2. 打开Xshell8,选择"新建",选择"新建用户密钥生成向导" 给用户

    10分钟前
    00
  • windows切换系统版本

    powershell 管理员身份打开 输入 irm massgrave.devget | iex 输入数字 对应后面写着 change windows edition新的会话框中选择想要的版本即可 获取windows 密钥 官方提供的

    8分钟前
    00
  • 【赵渝强老师】创建PostgreSQL的数据库

    在PostgreSQL中,创建数据库主要通过SQL命令“create database”完成,视频讲解如下:下面是具体的操作步骤。(1)查询现有数据库的集合,可以检查系统目录pg_database。代码语言:sql复制postgres=#

    6分钟前
    00
  • 设计模式:工厂方法模式(Factory Method)(2)

    当年做一个项目时,还不懂什么是设计模式,仅仅是按照经验完成了需求。回头看看,就是暗合桥接模式。但是,在整个需求实现过程中,甲方需要我在已经设计好的标准业务逻辑中添加非标的需求,因为,在他们眼里,从业务角度来看,是自然的拓展。如果当年我知道还

    5分钟前
    00
  • 解决Windows 10家庭单语言版语言限制:升级专业版全攻略

    解决Windows 10家庭单语言版语言限制:升级专业版全攻略 在日常使用Windows 10系统时,部分用户可能会遇到系统提示“当前许可证仅支持单一显示语言”的困扰。这一问题通常出现在预装或激活了Windows 10家庭单语言版的设备上

    2分钟前
    00

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信