角度:防止用户多次点击按钮

时间:2020-02-27 16:25:23

标签: angular firebase events button

我有一个带有firebase的小型movieDB应用程序。如果您在主页上搜索电影,您将看到从此开放的API中检索到的结果,现在通过路由进入了详细页面。在此页面中,您可以将评论发送到Firebase中的收藏,就像电影一样(都在同一节点中):

enter image description here

我的问题:阻止用户多次欣赏同一部电影。到目前为止,我有这个:

像组件HTML:

<button [disabled]="plus>1" (click)="increase()" class="btn btn-success">Like this Movie!</button>

像TS:

export class LikeComponent implements OnInit {
  @Output() change=new EventEmitter()
  plus:number=1;
  constructor() { }

  ngOnInit() {
  }

increase(){

  this.change.emit({like:this.plus++})
}

获取事件的详细HTML:

 <div class="col-md-6 form-group">
    <form [formGroup]="reviewForm" (ngSubmit)="submitReview()">
    <label for="review">Write your review!</label>
    <textarea class="form-control" rows="5" formControlName="review"></textarea>
    <button class="btn btn-success" [disabled]="reviewForm.invalid && likeable"  type="submit">Send review</button>
  </form>
  <app-like style="float:right" (change)="onChange($event)"></app-like>
  </div>

还有TS:

export class DetailComponent implements OnInit {
  id: string;
  userReviews:any;
  userName:string;
  likes:any;
  constructor(
    private movieService: MoviesService,
    private route: ActivatedRoute,
    private fb: FormBuilder,
    private location: Location,
    private authService: AuthService,
    private afAuth: AngularFireAuth,
    private localService: LocalService  ) {

      this.afAuth.authState.subscribe(user => {
        this.userName = user.displayName;
      })

  }

  ngOnInit() {
    this.route.paramMap
      .pipe(
        switchMap(params => {
          this.id = params.get("title");
          return this.movieService.getMovies(this.id);
        })
      )
      .subscribe(data => {
        this.movie = data
        //etc
  }

reviews(){
  this.reviewForm= this.fb.group({
    review: ['', Validators.required]
  })
}
get userReview(){return this.reviewForm.get('review')}

onChange(event){
  this.likes=event
}

submitReview(){
  if(this.likes===undefined){ //->firebase doesnt accept undefined
    this.likes=null
  }
let credentials = {
  author: this.userName,
  review: this.userReview.value,
  movie: this.id,
  likes: this.likes
}


  this.movieService.createReview(credentials).then(data=>{
    console.log(data)
  }).catch(error=>{
    console.log(error)
  })
}

如您所见,“ LIKE”按钮仅在plus变量具有多于一票的情况下可用。实际上,它可以工作,但是当我刷新页面或离开并返回时,该按钮再次可用。我该如何解决?有什么想法吗?谢谢

编辑(基于@JBoothUA提示的答案)

我这样实现了

export class LikeComponent implements OnInit {
  @Output() change=new EventEmitter()
  plus:number=1;
  local:any;
  constructor() { }

  ngOnInit() {
    this.local = JSON.parse(localStorage.getItem("plus"));
  }

increase(){
localStorage.setItem('plus', JSON.stringify( this.plus++))
  this.change.emit({like:this.plus++})
}

但没有结果。刷新后,该按钮再次可用。我在做什么错了?

编辑2 @ JBoothUA,@ Rahul Tokase和@Shravan

现在一切都可以使用以下代码:

export class LikeComponent implements OnInit {
  @Output() change = new EventEmitter()
  plus: number = 1;
  constructor() { }
  ngOnInit() {
  this.plus = +localStorage.getItem('plus')

  }

  increase() {
    localStorage.setItem('plus',''+ ++this.plus)
    this.change.emit({ like: this.plus++ })
  }

但是现在,这很合乎逻辑,现在用户不能投票其他任何电影,就像他只有一票对付成千上万的电影一样。我想我必须将此与他投票支持的特定电影联系起来。我要如何实现?这是正确的道路还是应该重做?

2 个答案:

答案 0 :(得分:1)

我不认为Angular可以在刷新期间自动存储状态。因此,您将不得不找到另一种存储变量的方法,因为Angular会在刷新时清除其内存。

您可以使用db或redis缓存之类的东西。

我会考虑将该值存储为本地存储,会话存储或cookie。

示例:

let key = 'Item 1';
localStorage.setItem(key, 'Value');
let myItem = localStorage.getItem(key);

localStorage和sessionStorage可以完成完全相同的工作并且具有相同的API,但是使用sessionStorage时,数据仅保留到关闭窗口或选项卡之前,而使用localStorage时,数据一直保留到用户手动清除浏览器缓存或直到您的网络应用会清除数据。

答案 1 :(得分:1)

您可以通过以下两种方式执行此操作。 1)有一个后端API,该API会显示“赞”状态,您可以根据状态禁用“赞”按钮。 2)您可以利用LocalStorage或SessionStorage tp存储状态。 3)利用NgRx商店来存储状态。

谢谢 拉胡尔