如何在Angular中让一个组件在按钮点击时删除自身

12 浏览
0 Comments

如何在Angular中让一个组件在按钮点击时删除自身

我无法让一个组件在Angular中自我删除。

我目前正在学习Angular,并为开始时启动了一个小的问候项目。应用程序的工作原理如下:

  1. 输入你的名字
  2. 创建一个向你问候的子组件。
  3. 子组件包含一个删除自身的按钮。

目前,我已经完成了前两个步骤,一切正常运行。但是我不知道如何让子组件删除自身。作为来自React的开发者,我知道在React中可以通过生命周期方法来删除一个"组件"。在Angular中是否有类似的方法呢?目前我找不到它,但我找到了一个名为"OnDestroy()"的方法,在一个组件被销毁之前调用。但是如何正确地销毁它呢?

父组件:

import { Component, OnInit, ViewChild, Input } from '@angular/core';
@Component({
  selector: 'app-greeter-service',
  templateUrl: './greeter-service.component.html'
})
export class GreeterServiceComponent implements OnInit {
  title = '';
  currentUser = '';
  isVisible = false;
  currentUsers: any[] = [];
  @ViewChild('newUser') inputField;
  constructor() {}
  greetingFunc(newUser : string) {
      if(newUser) {
      this.currentUsers.push(newUser);
      console.log(this.currentUsers);
      this.inputField.nativeElement.value='';
    }
  }
  ngOnInit() {
      this.title = 'Welcome to the Greeter!';
  }
}

子组件:

import { Component, OnInit, Input } from '@angular/core';
@Component({
  selector: 'app-was-greeted',
  templateUrl: './was-greeted.component.html',
  styleUrls: ['./was-greeted.component.scss']
})
export class WasGreetedComponent implements OnInit {
  @Input() user: string;
  constructor() { }
  deleteMe() {
    console.log("在这里应该有一个动作");
  }
  ngOnInit() {
  }
}

如何“动态”地将一个组件添加到应用程序中:

    

因此,对于数组"currentUsers"中的每个"push",都会创建一个组件。

0
0 Comments

问题的原因是想要在点击按钮时让一个组件自我删除。解决方法是:

1. 给组件添加一个参数,让父组件监听并从currentUsers中删除它,或者在*ngFor循环中添加额外的逻辑来忽略它。可以像下面这样实现:

2. 在组件中定义shouldDisplay函数,用于判断是否应该显示当前索引对应的元素。如果不需要显示,则返回false。

3. 在组件中定义removeMe函数,用于在按钮点击时触发删除操作。可以从currentUsers数组中移除对应的元素。

以上就是如何在Angular中实现在按钮点击时让一个组件自我删除的方法。通过添加监听参数并在循环中添加逻辑,可以实现组件的删除操作。

0
0 Comments

如何让一个Angular组件在按钮点击时删除自身

问题的出现原因:

目前已经完成了前两个步骤,一切都运行正常。但是我不知道如何让子组件删除自身。从React的经验来看,我知道可以通过生命周期方法删除“组件”。

解决方法:

1. 使用()绑定:在Angular中,组件可以具有一个在父组件模板中执行表达式的()绑定。这与将回调函数传递给React组件的属性相同。在WasGreetedComponent组件中,添加以下代码:

public closed: Subject() = new Subject();
deleteMe() { this.closed.next(); }

在GreeterServiceComponent模板中,更改以下代码:

2. 父组件注入:在Angular中,子组件可以通过构造函数注入自己的父组件,并直接通知父组件。这种方法绕过了模板,父组件中的任何更改都可能需要更新视图。因此,建议父组件使用ChangeDetectorRef将其视图标记为脏。

在GreeterServiceComponent中添加以下代码:

public deleteUser(user: any) {
    this.currentUsers = this.currentUsers.filter(u=>u !== user);
    this.changeDetectorRef.markForCheck();
}

在WasGreetedComponent中添加以下代码:

constructor(parent: GreeterServiceComponent) {}
deleteMe() { this.parent.deleteUser(this.user); }

3. 通过响应式编程实现全局状态:最后一种方法使用了响应式编程,其中使用可观察对象来允许消费者观察应用程序状态的变化。这样做的优点是状态由外部服务“拥有”和“管理”。在Angular/React/Vue框架中广泛使用的流行服务(如Redux/NGRX/NGXS)非常强大。使用状态存储有很多优点,但对于小型项目来说,它往往过于复杂。一旦开始使用它们,很难停止使用。

我们可以创建自己的小型版本作为演示。首先,添加一个表示应用程序状态的服务。

({provideIn: 'root'})
export class StateService {
    public users: BehaviorSubject = new BehaviorSubject([]);
    public addUser(user: any) {
        this.users
            .pipe(first())
            .subscribe(users => this.users.next([...users, user]));
    }
    public removeUser(user: any) {
        this.users
            .pipe(first())
            .subscribe(users => this.users.next(users.filter(u=>u !== user)));
    }
}

现在,在GreeterServiceComponent中,它将不再是状态的“所有者”。我们将注入上述服务,并允许该服务来管理它。

({...})
export class GreeterServiceComponent implements OnInit {
    constructor(public state: StateService) {}
    greetingFunc(newUser : string) {
        if(newUser) {
            this.state.addUser(newUser);
        }
    }
}

在GreeterServiceComponent模板中,我们将使用async管道直接从StateService中显示当前用户的状态。我们这样做是因为服务持有有关当前状态的“真相”。GreeterServiceComponent组件不关心如何更改它,因为它不拥有或管理它。

WasGreetedComponent组件将使用StateService来更改当前状态。该组件不关心其父组件。您可以在应用程序中移动此组件,并且它仍将正常工作。这是一个重要的好处,因为上述的其他方法依赖于DOM本身的结构。因此,移动一个组件将需要在其他地方进行更改以使组件正常工作。

({...})
export class WasGreetedComponent implements OnInit {
    constructor(public state: StateService) {}
    deleteMe() {
        this.state.removeUser(this.user);
    }
}

0
0 Comments

在Angular中,有时候需要在按钮点击时让一个组件自己删除。下面的内容提供了一种实现方法。

首先,在WasGreetedComponent组件中添加一个delete属性,并在按钮点击时触发一个事件。然后,在GreeterServiceComponent组件中通过查找数组中的元素并删除它来处理这个事件(注意,数组应该是不可变的,所以需要创建一个新的数组实例),这会导致ngFor重新评估并更新视图。

@Component({
  selector: 'app-was-greeted',
  templateUrl: './was-greeted.component.html',
  styleUrls: ['./was-greeted.component.scss']
})
export class WasGreetedComponent implements OnInit {
  @Input() user: string;
  @Output() delete: EventEmitter = new EventEmitter();
  constructor() { }
  deleteMe() {
    console.log("here should be the action");
    this.delete.emit(user);
  }
}

在父组件的模板中,订阅这个事件的触发。

然后,在父组件中处理deleteUser回调,并从数组中删除用户。

@Component({
  selector: 'app-greeter-service',
  templateUrl: './greeter-service.component.html'
})
export class GreeterServiceComponent implements OnInit {
  title = '';
  currentUser = '';
  isVisible = false;
  currentUsers: any[] = [];
  @ViewChild('newUser') inputField;
  constructor() {}
  ...
  deleteUser(user: string) {
    this.currentUsers = this.currentUsers.filter(x => x !== user);
  }
}

总之,这只是许多解决方法中的一种。希望对你有帮助。

0