简体   繁体   English

如何在 Angular 中淡入和淡出组件

[英]How to fade in and fade out component in Angular

I have a todo list app that I wrote in angular and I wanted to fade in each todo, when it is created and fade them out before they are deleted.我有一个以 angular 编写的待办事项列表应用程序,我想在每个待办事项创建时淡入淡出,并在删除它们之前淡出它们。 I was only able to get the fade in effect to work, if I apply the effect in the todo-item component, however the fade out effect wouldn't work.如果我在 todo-item 组件中应用效果,我只能让淡入效果起作用,但是淡出效果不起作用。 I've tried adding the animation to the parent todos component however, that doesn't work for either the fade in or fade out.我已经尝试将动画添加到父待办事项组件中,但是这对淡入或淡出都不起作用。

todos.component.ts (parent container of todo-items) todos.component.ts (todo-items 的父容器)

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 (parent container of todo-items) todos.component.html (todo-items 的父容器)

<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 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 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>

So I figured out the answer to my problem.所以我想出了我的问题的答案。 The fade effect won't apply to component tags.淡入淡出效果不适用于组件标签。 So in my todos.component.html (parent todo-item container) I created a div to wrap my todo-item tag in;所以在我的 todos.component.html(父 todo-item 容器)中,我创建了一个 div 来包装我的 todo-item 标签; and I applied the trigger name to it.我将触发器名称应用于它。

my modified todos.component.html我修改后的 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>

For Animations I often use https://animista.net/ they offer simple animations in css.对于动画,我经常使用https://animista.net/,它们在 css 中提供简单的动画。

To use them, you then only need to add the class to fade int, when clicking delete, you need to set the class for fading out - after the animation finished you really delete the object with a timer.要使用它们,您只需要将类添加到淡入淡出,单击删除时,您需要设置淡出类 - 动画完成后,您真正使用计时器删除对象。

When deleting you need to dynamically set it to another class something like that can work:删除时,您需要将其动态设置为另一个可以工作的类:

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

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

When deleting you also need to create a timer, such that the element is only deleted after the animation finished.删除时还需要创建一个计时器,以便在动画完成后才删除元素。 Example for a simple timer:一个简单的计时器示例:

// repeat with the interval of 2 seconds
let timerId = setInterval(() => alert('tick'), 2000);

// after 5 seconds stop
setTimeout(() => { clearInterval(timerId); alert('stop'); }, 5000);

Hope it helps!希望能帮助到你!

I have added one more field to ToDo class, status of perticular todo-item .我已经增加了一个领域ToDo类, status perticular的todo-item

Using this status , we can transition the animation state by binding the status property to @fade使用这个status ,我们可以通过将status属性绑定到@fade来转换动画状态

Demo 演示

Here, I am deleting any random item added in list.在这里,我将删除列表中添加的任何随机项目。

todo-parent.component.ts 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 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>

There is no need to do anything in your todo-item component.无需在您的todo-item组件中执行任何操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM