延迟加载TypeScript类的数据?

时间:2018-03-01 19:02:29

标签: angular rest typescript

我有一个Angular应用程序,它使用RESTful API来处理数据。我想要做的是构建我的数据对象,以便我只根据需要从服务器加载我需要的东西。

例如,如果我有一个Building个对象列表,每个对象都有tenants属性,我希望REST API向我发送一个带有int[]租户ID的构建对象而不是发送Tenant类型对象的数组。然后在我的应用程序中,我可以列出Building但仅在展开详细信息面板或其他内容时显示租户详细信息。此时,应用程序将通过其ID同步从RESTful API中获取单个Tenant个对象。这样我就不必在前面提取所有所有的所有租户。

这是Web应用程序中的正常模式吗?我无法找到任何资源,因为我不确定要搜索什么。我特别欣赏一些Angular特定的模式实现。

谢谢!

1 个答案:

答案 0 :(得分:0)

我一直在思考这个问题。一些可能的方法:

  1. 立即全部加载 - 正如您所提到的,您可以直接从 REST 服务器返回所有数据。这很方便,但不能很好地扩展,尤其是当您获得越来越多的嵌套数据结构时。如果它仅用于一级嵌套并且每个嵌套对象加载的数据量相对较小,或者不考虑性能和带宽,这可能适合您。

其余选项是异步获取数据的不同方法,其中您的 Building REST 路由返回带有可用于访问租户列表的 TenantsURL 的 Building 对象。

  1. Lazy TypeScript getter:在类中,您可以将变量隐藏在 getter 后面:

    class Building {
    
        public constructor(private readonly httpService: HttpClient){}
    
        public get tenants(): Observable<Tenant[]> {
            return this.httpService.get<Tenant[]>([url here]);
        }
    
    }
    

    这里的缺点是,如果您在 HTML 模板中使用租户,angular 将在每个更改检测步骤中调用此 getter 函数(请参阅此处:Why does this method/gettor get called X times in an Angular 2 service),这可能会变得相当昂贵,具体取决于延迟和数据大小.第二个缺点是,现在您需要将 HttpClient 服务(或某些自定义派生服务)注入到您的模型中,这会混淆服务和模型之间的水。

  2. 独立获取函数:对 #2 稍作修改,而不是使用 TypeScript getter,只需在您的模型上创建一个您可以调用的类方法:

    class Building {
    
        public constructor(private readonly httpService: HttpClient){}
    
        public constructor(){}
    
        public getTenants(httpService: HttpClient): Observable<Tenant[]> {
            return httpService.get<Tenant[]>([url here]);
        }
    
    }
    

    这将提供“getter”服务(本例中为 HttpClient)的负担从模型构建转移到需要获取租户的任何人身上,例如 Angular 组件。然后,您可以使用异步管道在 HTML 模板中显示值,或订阅角度组件。缺点是,由于这是一个函数,每次 angular 进行更改检测时都会调用它,这可能会严重影响性能。

  3. 管道:您可以创建一个自定义异步管道 TenantPipe,您可以向其中注入您需要的任何服务,以从建筑物 ({{3 }})。然后在 HTML 模板中,您可以简单地使用 Building 上的管道异步获取租户列表。请注意,如果您愿意,您可以使管道异步或将其与现有的角度异步管道链接在一起。这有利于将模型与 async get 功能清楚地分开,同时还确保 angular 在每个更改检测周期(而不是在每个更改检测步骤!)只运行一次管道。显然,这更侧重于 HTML 模板,但您也可以将管道注入组件打字稿,以便它可以在那里工作。

  1. 服务:使用方法 TenantService 制作服务 getTenantFromBuilding(building: Building): Observable<Tenant[]>。在您需要的任何地方,在您的打字稿组件中使用它。这里的功能与#4 非常相似,只是打包为服务而不是注入服务的管道。这更侧重于打字稿,但很明显,无论您从服务中获得什么价值,都可以在 HTML 模板中显示。

每种方法都有利有弊,我认为选择合适的方法取决于具体情况。