【问题标题】:Angular 2: sharing data across different routesAngular 2:跨不同路由共享数据
【发布时间】:2016-08-11 09:32:31
【问题描述】:

我在 SO 中搜索过类似的问题,但没有找到任何可以解决我的具体情况的问题。 Angular组件之间共享数据的技术有很多,我看过这篇关于组件通信的文章:https://angular.io/docs/ts/latest/cookbook/component-communication.html

但是那里描述的所有技术都不适合我,因为我的组件在不同的路线上。这篇文章主要描述了父子组件的通信,有些情况可能适用于兄弟组件,只要它们同时加载即可。

我的案例与 Angular 2 Heroes 教程非常相似:我有一个路由,它显示一个包含客户列表(而不是英雄)的表格。当用户点击特定客户时,我会触发路线更改以显示包含所选客户(而不是英雄)数据的表单。

英雄教程执行服务调用以检索选定的英雄数据,但我想避免无用的额外 AJAX 调用,因为这些数据已经在内存中。我只想将选定的客户数据传递给客户表单组件,以便立即显示。

我正在考虑一个“全局会话”服务,我可以在其中存储和检索我想要的任何对象,但我不确定这是一个好主意。还有其他更合适的方法吗?

【问题讨论】:

    标签: javascript angular


    【解决方案1】:

    您如何看待受 Redux 启发的 NgRx 解决方案?你可以在那里阅读更多信息 - https://github.com/ngrx/store

    您将拥有一个应用商店,可以在适当的组件中订阅该应用商店。所以 - 你可以在路由改变之前调度一个事件。此解决方案仅使用 reducer,因此与使用 store 不同的方式是,您的数据将是不可变的 - 这是下一个优势。

    【讨论】:

    • 谢谢,我很快查了一下,似乎是关于在 Angular 中采用 Redux 哲学。我会仔细阅读的……
    • 非常有趣,但这看起来像是一种“全有或全无”的方法,即在我的所有应用程序中使用,而不仅仅是解决这个特定问题。我是 Redux 的忠实粉丝,所以我会在未来的项目中考虑它。
    【解决方案2】:

    使用主应用程序文件提供的服务,然后在您想要获取/设置整个应用程序中可用的数据时注入它

    main.app.ts

    @Component({
    ...
      providers:[yourDataService]
    ...
    })
    

    其他组件

    import {yourDataService} from '...';
    
    @Component({
    ...
    providers:[]// we must use provider from main file
    ...
    })
    export class someComponent{
    
      contructor(private myData:yourDataService){}
    
    }
    

    使用主应用程序文件中的提供程序很重要,因为如果您在每个组件中提供服务,您将拥有另一个服务实例,当然每个服务中都有不同的数据

    您也可以使用observables 在某些数据发生更改时收到通知

    更多信息请查看hierarchical injectionstree injector

    【讨论】:

    • 这看起来类似于我的“全局会话”服务。 “yourDataService”的 API 是什么样的?像 setCustomer() / getCustomer() 这样的东西?
    • @Luis Crespo 是的,我认为这是最简单也是最好的方法
    • 谢谢。因为这几乎是我正在考虑的,所以我会再等一会儿,看看是否有人提出了一些替代方法。对于这样一个常见的场景,不得不在应用程序级别开发这种服务对我来说似乎很奇怪。也许 Angular 2 已经提供了一些更简单的机制。
    • 关于 observables 编辑:鉴于当用户从客户列表中选择特定客户时我的“客户详细信息”组件尚未加载,当“客户选择”时它不会注册为侦听器" 事件被触发。在这种情况下我的组件还会收到通知吗?
    • Luis Crespo,该服务是一种有效的方法。唯一的区别是您的服务是有状态的并且是单例的。想象一个您的服务将查询数据库或 Web 服务的世界...您的组件应该调用一个服务来查询它的数据。 .您可以通过创建一个缓存对象来更改 statefullness,(它将按照@neutronet 建议的服务启动并注入到 CustomerService 中),因此至少您的服务将是无状态的,并且您不必在 main.app 中启动它。 ts。
    【解决方案3】:

    我不确定这是否是您所追求的,但如果您需要跨兄弟路由共享数据,您可以试试这个。

    创建模块导入并声明模块中的服务

    import { MyService } from './my.service’;
    
    @NgModule({
      ...
      providers: [
        MyService
      ]
      …
    })
    

    在模块路由中声明服务意味着我们可以通过引用子路由来传递服务。不要在父组件中使用服务

    在子路由组件中,导入服务

    import { MyService } from '../my.service’;
    

    在每个应该使用服务的组件中,不要将服务添加到组件元数据中,因为我们已经将它添加到模块定义中。将服务添加到组件构造函数中

    export class MyChildRouteComponent implements OnInit {  
    ...
     constructor(
        private _myService: MyService,
        private _router: Router
      ) { }
     ...
    }
    

    如果您随后在一个子路由组件中设置服务属性,您将能够从同级子组件中获取它。

    【讨论】:

    • 是的,这正是我正在做的 :-)
    猜你喜欢
    • 2017-06-29
    • 1970-01-01
    • 2017-09-18
    • 2020-01-25
    • 2020-08-27
    • 2017-11-07
    • 1970-01-01
    • 2017-01-04
    • 1970-01-01
    相关资源
    最近更新 更多