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

时间:2019-12-22 16:04:17

标签: javascript html angular animation

我有一个待办事项列表应用程序,该应用程序是我用角度编写的,我想在创建每个待办事项时使其淡入淡出,并在删除它们之前使其淡出。如果将效果应用到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>

3 个答案:

答案 0 :(得分:0)

对于动画我经常使用https://animista.net/,它们在CSS中提供简单的动画。

要使用它们,您只需要添加要逐渐淡入淡出的类,在单击“删除”时,您需要设置要淡出的类-动画完成后,您确实使用计时器删除了该对象。

删除时,您需要将其动态设置为另一个类,这样可以起作用:

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

希望有帮助!

答案 1 :(得分:0)

我为Boo的{​​{1}}类的ToDo类又增加了一个字段。

使用此status,我们可以通过将todo-item属性绑定到status

来转换动画状态

Demo

在这里,我要删除列表中添加的所有随机项目。

todo-parent.component.ts

status

todo-parent.component.html

@fade

@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); } } 组件中无需执行任何操作。

答案 2 :(得分:0)

所以我想出了解决我问题的答案。淡入淡出效果不适用于组件标签。因此,在我的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>