简体   繁体   English

带有图像的模态对话框仅在用户第一次加载页面时显示

[英]Modal dialog with image show only the first time a user loads the page

Hello everyone I'm new to front-end development and I'm using Angular 11, Angular material and Bootstrap for a project, my problem is I want to show a pop up with and ad the first time a user loads the home page, the modal dialog is made in angular material, I have the modal dialog in ads component and then call it in the home component on the ngOnInit so the dialog will show when the user loads the home page, I found some solutions using JS but didn't make them work for me, any help on how can I solve this?大家好,我是前端开发的新手,我正在使用 Angular 11、Angular 材料和 Bootstrap 进行项目,我的问题是我想在用户第一次加载主页时显示一个弹出窗口和广告,模态对话框是在 angular 材料中制作的,我在 ads 组件中有模态对话框,然后在 ngOnInit 的主页组件中调用它,因此对话框将在用户加载主页时显示,我找到了一些使用 JS 的解决方案,但没有不让他们为我工作,我该如何解决这个问题有什么帮助吗?

My ads component html, I'm only showing the image, no button to close the modal but if I need to add a button for a solution, I can add the button.我的广告组件 html,我只显示图像,没有关闭模式的按钮,但如果我需要为解决方案添加按钮,我可以添加按钮。

<mat-dialog-content id="myModal" class="gradient-border">
  <img style="max-width: 100%;" src="../../../assets/img/modal-ad.jpg">
</mat-dialog-content>

ads component ts广告组件 ts

import { Component, OnInit } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';


@Component({
  selector: 'app-anuncios',
  templateUrl: './anuncios.component.html',
  styleUrls: ['./anuncios.component.css']
})


export class AnunciosComponent implements OnInit {

  constructor(public dialogRef: MatDialogRef<AnunciosComponent>) { }

  ngOnInit(): void {
  }
}

Home component ts家庭组件 ts

import { Component, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { AnunciosComponent } from '../anuncios/anuncios.component';


@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})



export class HomeComponent implements OnInit {

  constructor(public dialog: MatDialog) { }

  ngOnInit(): void {
    this.showDialog();
  }

  showDialog(){

    const dialogRef = this.dialog.open(AnunciosComponent, {
      maxWidth: "100vw", 
      maxHeight: "150vw",
      panelClass: ['animate__animated','animate__bounceInDown']
    
    }); 
  }

  
}

So this code makes the modal dialog always show when the home page is load, I need to show it the first time the user load the home page, I saw some solutions using cookies or JS functions but didn't make them work for me, as I said, I'm new to this and I think I didn't use those solutions properly for my project, any suggestions will be appreciated.所以这段代码使模态对话框总是在主页加载时显示,我需要在用户第一次加载主页时显示它,我看到一些使用 cookies 或 JS 函数的解决方案,但没有让它们对我有用,正如我所说,我是新手,我认为我没有为我的项目正确使用这些解决方案,任何建议都将不胜感激。

If in order to achieve what you mean you need to "remember" if the user has already seen the dialog.如果为了实现您的意思,您需要“记住”用户是否已经看到了对话框。

Now I have another question for you:现在我还有一个问题要问你:

  1. Does the user need to see this every time the page loads?用户是否需要在每次页面加载时都看到这个?
  2. Once and never again?一次又一次?
  3. Every time he initiates a session on your site?每次他在您的网站上发起 session 时? (opens the browser to browse your site) (打开浏览器浏览您的网站)

If your use-case is like option 1, then you might just have an internal variable.如果您的用例类似于选项 1,那么您可能只有一个内部变量。 You can either use a static variable with a boolean or use a singleton Service from Angular.您可以使用static变量和 boolean 或使用 ZC31C335EF37283CDE1ZDDB 的 singleton 服务。

@Component({...})
export class MyComponent {
  public static hasAdvertBeenShown = false

  ngOnInit() {
     if(!MyComponent.hasAdvertBeenShown) {
        this.matRef.showDialog()
        MyComponent.hasAdvertBeenShown = true
     }
  }

}

If your use-case is to show the advertisement the first time the user browses your site then your variable would be stored inside localStorage and it would survive opening and closing the browser.如果您的用例是在用户第一次浏览您的网站时显示广告,那么您的变量将存储在localStorage中,并且它可以在打开和关闭浏览器时继续存在。

@Component({...})
export class MyComponent {
  public static hasAdvertBeenShown = MyComponent.hasAdvertBeenShownBefore()

  ngOnInit() {
     if(!MyComponent.hasAdvertBeenShown) {
        this.matRef.showDialog()
        MyComponent.markAsSeen()
     }
  }

  public static boolean hasAdvertBeenShownBefore() {
    return JSON.parse(localStorage.getItem('advert'))
  }
  public static boolean markAsSeen() {
    localStorage.setItem('advert', true)
  }

}

If your use-case is the latter then use sessionStorage is similar to localStorage but it's shorter lived (per session)如果您的用例是后者,那么使用sessionStorage类似于localStorage但它的寿命较短(每个会话)

@Component({...})
export class MyComponent {
  public static hasAdvertBeenShown = MyComponent.hasAdvertBeenShownBefore()

  ngOnInit() {
     if(!MyComponent.hasAdvertBeenShown) {
        this.matRef.showDialog()
        MyComponent.markAsSeen()
     }
  }

  public static boolean hasAdvertBeenShownBefore() {
    return JSON.parse(sessionStorage.getItem('advert'))
  }
  public static boolean markAsSeen() {
    sessionStorage.setItem('advert', true)
  }

}

If you'd like to know more about local and session storages you can take a read over here如果您想了解更多关于本地和 session 存储的信息,您可以在此处阅读

Here's what I usually do in my apps这是我通常在我的应用程序中做的事情

Whenever I need to store something into localStorage, let that be preferences (user settings, dark-mode, etc.) and I want that to survive browser restarts I need to use localStorage.每当我需要将某些内容存储到 localStorage 中时,就让它成为首选项(用户设置、暗模式等),并且我希望它能够在浏览器重新启动后继续存在,我需要使用 localStorage。

Since using raw localStorage can get messy quite easily what I do is just create a singleton "UserSettingsService" that wraps the "low-level" local storage logic so I can share it across the codebase:由于使用原始 localStorage 很容易变得混乱,我所做的只是创建一个 singleton “UserSettingsService”,它包装了“低级”本地存储逻辑,以便我可以在代码库中共享它:

@Inject({providedIn: 'root'})
export class SettingsService {
  private storage: Storage = localStorage // Change this based on your use-case

  public markAdvertisementAsShown() {
    this.storage.setItem('advert', true)
  }

  public boolean hasAdvertisementBeenShown() {
    const safeBoolean = this.storage.getItem('advert') ?? 'false' // defaulting to false in case it didnt exist
    return JSON.parse(safeBoolean)
  }

}

And then on my other classes:然后在我的其他课程上:

@Component({...})
export class SomeComponent {
   hasAdvertBeenShown = this.adverts.hasAdvertisementBeenShown()
  constructor(private matRef: Mat..., private adverts: AdvertService){}

  ngOnInit() {
    if(!this.hasAdvertBeenShown) {
      // do something like showing the advert
      this.adverts.markAdverisementAsShown()
    }
  }
}

It might seem a little overkill for a boolean but apps tend to get more and more complex.对于 boolean 来说,这似乎有点矫枉过正,但应用程序往往会变得越来越复杂。 Like you'd like later you want to show 3 diferent advertisements and you need to be sure which one you've shown.就像您稍后想要显示的 3 个不同的广告一样,您需要确定您显示的是哪一个。 Now you wouldn't be serializing the boolean but rather the advertisement object that has been shown.现在您不会序列化 boolean 而是序列化已显示的广告 object。 Logic gets more complex but because it's in a service you would only change it there and boom it's working again throughout your app!逻辑变得更加复杂,但是因为它在服务中,所以您只需在那里更改它,然后在整个应用程序中再次运行它!

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

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