服务初始化一次但不是第二次

Posted

技术标签:

【中文标题】服务初始化一次但不是第二次【英文标题】:Service initializing once but not a second time 【发布时间】:2020-04-21 10:43:38 【问题描述】:

我刚刚在我一直在玩的应用中发现了一个错误,这对我来说似乎没有意义。

问题:我在不同的 MatTab 上有两个组件。 每个都正确实例化并在选项卡更改之间被破坏。我的 Post 服务正在返回一个 observable 并完美地填充我的数据表。所以就像一个愚蠢的孩子,我进入我的服务并尝试清理代码。从以下位置更改 Post Service 后:

     constructor(private afs: AngularFirestore, private router:Router, ) 
    this.postsCollection = afs.collection<Post>(config.collection_endpoint);

    this.posts = 
      this.afs.collection('posts').snapshotChanges()
      .pipe(map(actions => actions.map(this.documentToDomainObject)));
      
     getPosts()
    return  this.afs.collection('posts').snapshotChanges()
    .pipe(map(actions => actions.map(this.documentToDomainObject)));
   

这很好,但我重复了自己,所以我决定清理它 - 将其更改为:

constructor(private afs: AngularFirestore, private router:Router, ) 
    this.postsCollection = afs.collection<Post>(config.collection_endpoint);

    this.posts = 
      this.afs.collection('posts').snapshotChanges()
      .pipe(map(actions => actions.map(this.documentToDomainObject)));
     getPosts()
    return this.posts;

更改代码后,我只得到一个填充的实例。发生这种情况是否有原因?对我来说,这是相同的代码,我知道这里有一些我不理解的东西,但我一生都无法找出它是什么。实例化服务的方式是否有我在这里看不到的东西?再次感谢。

这里是 feed.component,以防您也需要。抱歉,我似乎无法在此处正确发布代码。

export class FeedComponent implements OnInit, 
    OnChanges, OnDestroy 
    postData: Post[] = [];
    subDepartmentSelections: string[] = []
    filteredData: any[] = []
    dataReady: boolean = false;
    dataSource: MatTableDataSource<any> = new 
       MatTableDataSource;
    displayedColumns: string[] = ['User', 'Title', 
    "Description", "Date Available", "Contact"]

    posts = this.ps.getPosts();

    currentDepartment: string = ""
    constructor(private ps: PostService, public dialog: 
    MatDialog, public change: ChangeDetectorRef, public 
    ms: MessageService) 
    ngOnInit() 
    this.refreshPosts()
    console.log("this is refreshing and data ready = " + this.dataReady)
  

    refreshPosts() 

    this.posts.subscribe(posts => 

      this.dataReady = false;
      this.postData = posts.filter(post =>
        post.uid != `$this.currentUser.uid` &&
        post.claimedBy != `$this.currentUser.uid`);
        this.dataSource = new 
        MatTableDataSource(this.postData)
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort
        this.dataReady = true;
        console.log("this is refreshing and data ready = " + this.dataReady)
     );

【问题讨论】:

你们在哪里提供服务?如果您想要 2 个服务实例,请在您的组件中提供它,如下所示:codecraft.tv/courses/angular/dependency-injection-and-providers/… @OdedBD 每次初始化组件时都会在 ngOnInit 期间调用它。我只想要一个实例,但让我感到困惑的是,除非我保持我的代码原来的样子,否则它不会第二次实例化。 【参考方案1】:

根据您提供服务的位置,它会被实例化。这意味着,您可以通过在服务中使用它来拥有单例服务:

@Injectable()
providedIn: 'root'

或将其作为依赖项添加到单个模块的“提供者”数组中。

但是要在组件中使用它时每次都重新实例化它,您可能应该在组件级别提供它:

@Component(
 selector: 'your-component',
 template: `...`,
 providers: [ NonSingletonService]
)

【讨论】:

以上是关于服务初始化一次但不是第二次的主要内容,如果未能解决你的问题,请参考以下文章

Streambuilder 渲染两次,第一次使用初始数据,第二次使用正确数据,但小部件不更新

我的应用程序第二次没有初始化/地理定位插件

TCP 三次握手(相当于寄信需要回执,第一次握手:我寄给你一封信。第二次握手:你回我一封信。第三次握手:我再给你一个回执,这样你才能确认我收到信了)

第二次作业

尝试第二次访问 json 文件时访问被拒绝

viewer 图片查看器,图片显示不全和第二次图片查看无法初始化的bug