2016-10-15 24 views
6

những gì tôi đang cố gắng để làm:Làm thế nào để sử dụng ResolveComponentFactory() nhưng với một chuỗi như một chìa khóa

  • Sử dụng một cái gì đó tương tự như "resolveComponentFactory()", nhưng với một 'chuỗi' nhận dạng để có được Nhà máy thành phần.
  • Khi đã có được, hãy bắt đầu sử dụng phương thức "createComponent (Factory)".

Plnkr Ví dụ ->enter link description here

Trong ví dụ, bạn sẽ thấy những "AddItem" phương pháp

addItem(componentName:string):void{ 
    let compFactory: ComponentFactory; 
    switch(componentName){ 
     case "image": 
      compFactory = this.compFactoryResolver.resolveComponentFactory(PictureBoxWidget); 
      break; 
     case "text": 
      compFactory = this.compFactoryResolver.resolveComponentFactory(TextBoxWidget); 
      break; 
} 

//How can I resolve a component based on string 
//so I don't need to hard cost list of possible options 


this.container.createComponent(compFactory); 

}

Các "compFactoryResolver: ComponentFactoryResolver" được tiêm trong contructor .

Như bạn sẽ lưu ý, việc phải mã hóa cứng mọi hoán vị trong câu lệnh chuyển đổi ít hơn lý tưởng.

khi ghi lại ComponentFactoryResolver vào bảng điều khiển, tôi đã quan sát thấy nó chứa Bản đồ với các nhà máy khác nhau.

CodegenComponentFactoryResolver {_parent: AppModuleInjector, _factories: Map} 

Tuy nhiên, bản đồ này là riêng tư và không thể dễ dàng truy cập (từ những gì tôi có thể biết).

Có giải pháp nào tốt hơn không thì bằng cách nào đó sẽ lăn lớp của riêng tôi để truy cập vào danh sách nhà máy này?

Tôi đã nhìn thấy rất nhiều thông báo về những người đang cố tạo các thành phần động. Tuy nhiên, đây thường là về việc tạo các thành phần trong thời gian chạy. các thành phần được đề cập ở đây đã được xác định trước, tôi đang cố gắng truy cập các nhà máy bằng cách sử dụng một chuỗi làm khóa.

Bất kỳ đề xuất hoặc lời khuyên nào được đánh giá cao.

Cảm ơn bạn.

+1

Làm cách nào để bạn có thể mong đợi lớp được xác định bằng một chuỗi nếu chuỗi đó không được xác định bởi một chuỗi nội bộ? Tên của lớp 'PictureBoxWidget' giống như' a' trong ứng dụng được rút gọn, và tên của lớp 'TextBoxWidget' có thể là' a'. Bạn có thể duy trì bản đồ thành phần của riêng bạn, nhưng bạn cần liệt kê chúng một cách rõ ràng. Nó luôn luôn là cách tiếp cận vững chắc hơn để có một danh sách cố định các lựa chọn thay thế có thể được xác nhận và thử nghiệm. – estus

Trả lời

6

Nó hoặc là xác định một bản đồ của các thành phần có sẵn,

const compMap = { 
    text: PictureBoxWidget, 
    image: TextBoxWidget 
}; 

Hoặc xác định định danh là tài sản lớp tĩnh sẽ được sử dụng để tạo ra một bản đồ,

const compMap = [PictureBoxWidget, TextBoxWidget] 
.map(widget => [widget.id, widget]) 
.reduce((widgets, [id, widget]) => Object.assign(widgets, { [id]: widget }), {}); 

Bản đồ này sau đó được sử dụng như

let compFactory: ComponentFactory; 

if (componentName in compMap) { 
    compFactory = this.compFactoryResolver.resolveComponentFactory(compMap[componentName]); 
} else { 
    throw new Error(`Unknown ${componentName} component`); 
} 

Không có cách nào các lớp thành phần có thể được xác định một cách kỳ diệu dưới dạng chuỗi s, bởi vì chúng không được giải quyết thành chuỗi trong Angular 2 DI (một cái gì đó đã được thay đổi kể từ Angular 1, trong đó tất cả các đơn vị DI được chú thích dưới dạng chuỗi).

+0

Cảm ơn bạn đã phản hồi. Tôi sẽ xem xét để tích hợp điều này vào giải pháp mà tôi hiện đang làm việc. – Edward

+0

@DeveloperWonk Không, có nhu cầu. Xem https: // stackoverflow.com/a/39522406/3731501 – estus

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