2016-08-18 20 views
6

Theo sự hiểu biết của tôi về Angular 2 rc5, để thực hiện dịch vụ từ mô-đun khác (không phải AppModule) có sẵn như là một singleton cho mọi thành phần, ngay cả những người lười biếng, chúng tôi don 't bao gồm dịch vụ trong mảng providers của mô-đun kia. Chúng tôi thay vì xuất khẩu nó với RouterModule.forRoot() và nhập kết quả trong AppModuleGóc 2 Làm thế nào để làm cho dịch vụ đơn có sẵn cho các mô đun nạp lười

According to the docs:

The SharedModule should only provide the UserService when imported by the root AppModule. The SharedModule.forRoot method helps us meet this challenge...the SharedModule does not have providers ...When we add the SharedModule to the imports of the AppModule, we call forRoot. In doing so, the AppModule gains the exported classes and the SharedModule delivers the singleton UserService provider at the same time

Tôi thực sự đấu tranh với làm thế nào để tạo ra một dịch vụ của bên thứ 3 (một dịch vụ được sử dụng bởi một module trong mảng imports trong số AppModule) của tôi có sẵn cho các tuyến đường được tải lười biếng. Tôi không có quyền kiểm soát mô-đun bên thứ ba này, vì vậy tôi không thể chỉ xóa dịch vụ đó khỏi mảng NgModule.providers của mô-đun đó và đặt nó vào bên trong RouterModule.forRoot() như tôi thực hiện với một trong các dịch vụ của mình.

Dịch vụ cụ thể là MdIconRegistry, nằm trong số providers cho số MdIconModule của Angular Material 2 alpha 7-3. Dịch vụ này được sử dụng để đăng ký các biểu tượng svg mà sau đó có thể được hiển thị trên trang với thẻ <md-icon svgIcon='iconName'>. Vì vậy:

  • tôi nhập khẩu MdIconModule trong thư mục gốc của tôi AppModule
  • tôi đã sử dụng các dịch vụ liên quan đến đăng ký biểu tượng svg trong tôi AppComponent

Biểu tượng có thể nhìn thấy và hoạt động tốt, nhưng chỉ trong các module đã được tải khi khởi chạy. Các mô-đun nạp lười không thể thấy các biểu tượng này, vì vậy tôi nghi ngờ rằng đầu phun Angular không tiêm cùng một thể hiện của dịch vụ MdIconRegistry.

tl; dr: Tôi làm cách nào để dịch vụ từ mô-đun bên thứ ba trở thành đơn có sẵn cho các thành phần được tải lười biếng của tôi?

Here is a plunker that demonstrates the problem (được mã hóa trong typescript).

PS: Đây chỉ nhận được sự chú ý của các nhà phát triển MdIconModuleon github.

Trả lời

8
I do not think it has anything to do with the component being lazy-loaded. 

LazyLoadedComponent không phải là một phần của AppModule - đó là một phần của LazyModule. Theo các tài liệu, một thành phần chỉ có thể là một phần của một mô-đun. Nếu bạn thử thêm LazyLoadedComponent vào AppModule, bạn sẽ gặp phải lỗi với hiệu ứng đó. Vì vậy, LazyLoadedComponent thậm chí không thấy MdIconModule. Bạn có thể xác nhận điều này bằng cách nhìn vào đầu ra mẫu trong trình gỡ rối - nó không thay đổi.

<md-icon svgIcon="play"></md-icon> 

Giải pháp dường như thêm MdIconModule vào LazyModule và trong khi điều này không khắc phục được sự cố, nó sẽ thêm lỗi vào đầu ra.

Error retrieving icon: Error: Unable to find icon with the name ":play"

Và đầu ra mẫu bây giờ trông như thế này, vì vậy chúng tôi biết nó đang tải.

<md-icon role="img" svgicon="play" ng-reflect-svg-icon="play" aria-label="play"></md-icon> 

tôi đã thêm các cuộc gọi đến addSvgIconSet từ LazyLoadedComponent, và điều đó đã nhận nó làm việc ... vì vậy đây chứng tỏ có một thể hiện của các dịch vụ MdIconRegistry mỗi thành phần - không phải những gì bạn muốn, nhưng có thể chỉ cho bạn đi đúng hướng.

Đây là liệng mới - http://plnkr.co/edit/YDyJYu?p=preview

Sau khi xem xét thêm, tôi thấy điều này trong docs:

Why is a service provided in a lazy loaded module visible only to that module?

Unlike providers of the modules loaded at launch, providers of lazy loaded modules are module-scoped.

Cập nhật cuối cùng! Đây là câu trả lời. MdIconModule không được thiết lập đúng cho các thành phần được nạp lười ... nhưng chúng ta có thể dễ dàng tạo mô-đun riêng của mình được thiết lập và sử dụng đúng cách.

import { NgModule } from '@angular/core'; 
import { HttpModule } from '@angular/http'; 

import { MdIcon } from '@angular2-material/icon'; 
import { MdIconRegistry } from '@angular2-material/icon'; 

@NgModule({ 
    imports: [HttpModule], 
    exports: [MdIcon], 
    declarations: [MdIcon] 
}) 
export class MdIconModuleWithProviders { 
    static forRoot(): ModuleWithProviders { 
    return { 
     ngModule: MdIconModuleWithProviders, 
     providers: [ MdIconRegistry ] 
    }; 
    } 
} 

Đã cập nhật và hoạt động hoàn toàn. (xin lỗi, cập nhật cùng một tài khoản) ->http://plnkr.co/edit/YDyJYu?p=preview

Bạn có thể gửi yêu cầu kéo để Vật liệu góc xuất mô-đun của cả hai kiểu.

+0

Hey James cảm ơn rất nhiều vì phản hồi của bạn. Bạn thực hiện một điểm tốt về việc nhập 'MdIconModule' vào' LazyModule' và tôi sẽ tải lên plunker của tôi để phản ánh nó. Vẫn còn một vấn đề: khi bạn phát hiện ra, bạn cần gọi lại 'addSvgIconSet()' vì 'MdRegistryService' không phải là một singleton. Tuy nhiên, việc tải tập hợp biểu tượng trong mỗi mô-đun là không thực tế vì nó có nghĩa là một yêu cầu http mới cho cùng một tệp 'svg' được thực hiện ở mọi thay đổi tuyến đường. Câu hỏi đầu tiên của tôi vẫn là: Làm thế nào tôi có thể làm cho dịch vụ này ('MdIconRegistry') một singleton có sẵn cho' LazyModule'? – BeetleJuice

+0

Đúng, tôi đã cập nhật câu trả lời. Dường như DOES này phải làm gì với tải chậm và phạm vi bị hạn chế bởi thiết kế. – James

+0

Góc cung cấp các cơ sở để thực hiện một dịch vụ đơn lẻ áp dụng ngay cả đối với các tuyến đường lười (tôi thảo luận với các liên kết trong OP). Điều này đòi hỏi các mô-đun phải được viết theo một cách nào đó (các dịch vụ không nên được đặt trong mảng 'provider' hoặc một cá thể mới sẽ được đưa vào tất cả mọi thứ nhập khẩu mô-đun). Thách thức ở đây là tôi phải đối mặt với một dịch vụ chỉ hữu ích như một singleton, nhưng mô đun của nó không được viết là "đúng cách" và mô-đun của tôi không có quyền kiểm soát. Tôi cũng đã báo cáo ở đây: https://github.com/angular/material2/issues/1071 – BeetleJuice

Các vấn đề liên quan