【问题标题】:How to fade in and fade out component in Angular如何在Angular中淡入和淡出组件
【发布时间】:2019-12-22 16:04:17
【问题描述】:

我有一个以角度编写的待办事项列表应用程序,我想在每个待办事项创建时淡入淡出,并在它们被删除之前淡出它们。如果我在 todo-item 组件中应用效果,我只能让淡入效果起作用,但是淡出效果不起作用。我已经尝试将动画添加到父 todos 组件,但是对于淡入或淡出都不起作用。

todos.component.ts(待办事项的父容器)

animations: [
    trigger('fade', [      
      transition('void => *', [
        style({opacity: 0}),
        animate(1000, style({opacity: 1}))
      ]),
      transition('* => void', [
        animate(1000, style({opacity: 0}))
      ])
    ])

]
})
export class TodosComponent implements OnInit {
  todos:Todo[];
  constructor(private todoService:TodoService) {
   }

  ngOnInit() {
    this.todoService.getTodos().subscribe(todos=> { this.todos = todos});
  }
  deleteTodo(todo:Todo){
    this.todos.splice(this.todos.indexOf(todo), 1);
    this.todoService.deleteTodo(todo).subscribe();
  }
  addTodo(todo:Todo){
    this.todoService.addTodo(todo).subscribe(todo=>{
      this.todos.push(todo);

    })
  }
}

todos.component.html(待办事项的父容器)

<app-add-todo (addTodo)="addTodo($event)"></app-add-todo>
<app-todo-item 
@fade
*ngFor="let todo of todos" 
[todo] = "todo"
(deleteTodo)="deleteTodo($event)"
>
</app-todo-item>

todo-item.component.ts

export class TodoItemComponent implements OnInit {
  @Input() todo: Todo;
  @Output() deleteTodo: EventEmitter<Todo> = new EventEmitter();

  setClasses(){
    let classes = {
      todo: true,
      'is-complete': this.todo.completed
    }

    return classes
  }
  onToggle(todo) {
    todo.completed = !todo.completed;
    this.todoService.toggleCompleted(todo).subscribe( todo => console.log(todo));
  }
  onDelete(todo){
    this.deleteTodo.emit(todo);
  }
  constructor(private todoService:TodoService) { }

  ngOnInit() {
  }

}

todo-item.component.html

<div [ngClass] = "setClasses()">
    <p>
        <input (change)="onToggle(todo)" type="checkbox"/>
        {{todo.title}}
        <button (click)="onDelete(todo)" class="del">x</button>
    </p>   
</div>

【问题讨论】:

    标签: javascript html angular animation


    【解决方案1】:

    对于动画,我经常使用https://animista.net/,他们提供了简单的 css 动画。

    要使用它们,你只需要添加类为fade int,点击删除时,你需要设置类为淡出-动画完成后你真的用计时器删除对象。

    删除时需要将其动态设置为另一个可以工作的类:

    <div [className]="someValue"></div>
    

    (来自:https://malcoded.com/posts/angular-ngclass/

    删除的时候还需要创建一个定时器,这样元素只有在动画结束后才会被删除。简单计时器示例:

    // repeat with the interval of 2 seconds
    let timerId = setInterval(() => alert('tick'), 2000);
    
    // after 5 seconds stop
    setTimeout(() => { clearInterval(timerId); alert('stop'); }, 5000);
    

    希望对你有帮助!

    【讨论】:

    • 那么对于一个css效果,你会使用整个库吗?
    • @Plochie 什么库?我没有关注。
    • 好吧,如果你检查一下 - 你会意识到你只得到关键帧和 css 类,你需要将它们复制到你的项目 css - 对于你想要的东西,它不是图书馆。我真的建议您看一下 - 如果您已经检查过,请告诉我您的意见:)
    • 我已经检查并同意你的看法。
    【解决方案2】:

    我在ToDo 类中又添加了一个字段,status 和特定的todo-item

    使用这个status,我们可以通过将status属性绑定到@fade来转换动画状态

    Demo

    在这里,我正在删除列表中添加的任何随机项目。

    todo-parent.component.ts

    @Component({
      selector: 'app-todo-parent',
      templateUrl: './todo-parent.component.html',
      styleUrls: ['./todo-parent.component.css'],
      animations: [
        trigger('fade', [
          transition('void => active', [ // using status here for transition
            style({ opacity: 0 }),
            animate(1000, style({ opacity: 1 }))
          ]),
          transition('* => void', [
            animate(1000, style({ opacity: 0 }))
          ])
        ])
      ]
    })
    export class TodoParentComponent {
    
      todoList: {str: string, status: string}[] = [];
    
      addItem() {
        this.todoList.push({str: 'added :' + this.todoList.length, status: 'active'});
      }
    
      deleteRandom() {
        const num = Math.ceil(Math.random() * this.todoList.length);
        this.todoList.splice(num, 1);
      }
    }
    

    todo-parent.component.html

    <div style="width: 250px">
      <div *ngFor="let todo of todoList" [@fade]="todo.status"> <!-- using status here for transition -->
        <app-todo-item [todoValue]="todo.str"></app-todo-item>
      </div>
    </div>
    

    您的todo-item 组件中无需执行任何操作。

    【讨论】:

    • 我会试试?????
    【解决方案3】:

    所以我找到了问题的答案。淡入淡出效果不适用于组件标签。所以在我的 todos.component.html(父 todo-item 容器)中,我创建了一个 div 来包装我的 todo-item 标签;我将触发器名称应用到它。

    我修改后的 todos.component.html

    <app-add-todo (addTodo)="addTodo($event)"></app-add-todo>
    <div @fade *ngFor="let todo of todos">
    <app-todo-item [todo] = "todo" (deleteTodo)="deleteTodo($event)">
    </app-todo-item>
    </div>
    

    【讨论】:

    • 刚刚在同样的情况下为我工作(想要淡出组件标签)。
    猜你喜欢
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多