2016-03-31 18 views
9

Kịch bản sau: Tôi xây dựng ứng dụng AngularJS 2 tiêu thụ API REST (có thể được xây dựng với Elixir hoặc RoR hoặc bất kỳ thứ gì). Trong quá trình phát triển, tôi muốn AngularJS tiêu thụ một API khác với trong sản xuất (có thể với dữ liệu thử nghiệm, có thể vì tôi xây dựng API cùng một lúc và nó chạy trên máy của tôi).AngularJS 2: Cách xử lý cấu hình ứng dụng cho các môi trường khác nhau

Ngoài ra, các thành viên khác trong nhóm của tôi có thể muốn sử dụng một địa chỉ API cục bộ khác. Điều đó có nghĩa là điều này không nên đi vào hệ thống kiểm soát phiên bản.

Vì vậy, ví dụ: api_base_url có thể là http://localhost:4000 đối với tôi, http://testapi.local cho đồng nghiệp của tôi và http://api.example.com để sản xuất.

Giá trị api_base_url sẽ có sẵn trong nhiều thành phần.

Cách tiếp cận tốt để xử lý vấn đề này là gì?

Trả lời

4

Bạn có thể xác định nhà cung cấp chuyên dụng đã cung cấp các gợi ý này. Một cái gì đó như thế:

bootstrap(AppComponent, [ 
    (...) 
    provide('configuration', { 
    useValue: { 
     apiBaseUrl: 'http://localhost:4000' 
    } 
    } 
]); 

Khi bạn đóng gói mã sản xuất, bạn có thể thay thế tệp có chứa mã này bằng mã có cấu hình sản xuất.

Để đưa vào tài khoản cấu hình này, bạn có thể mở rộng các lớp RequestOptions tiền tố tất cả các yêu cầu của bạn với apiBaseUrl tiền tố:

import { 
    BaseRequestOptions, RequestOptions, RequestOptionsArgs 
} from 'angular2/http'; 

export class AppRequestOptions extends BaseRequestOptions { 
    constructor(private @Inject('configuration') configuration:any) { 
    } 

    merge(options?:RequestOptionsArgs):RequestOptions { 
    options.url = this.configuration.apiBaseUrl + options.url; 
    return super.merge(options); 
    } 
} 

Đừng quên để cấu hình các tùy chọn yêu cầu khi bootstrapping ứng dụng của bạn:

bootstrap(AppComponent, [ 
    (...) 
    provide('configuration', { 
    useValue: { 
     apiBaseUrl: 'http://localhost:4000' 
    } 
    } 
    provide(RequestOptions, { useClass: AppRequestOptions }) 
]); 

Quá trình xử lý này có thể được chứa trong tệp JS chuyên dụng sẽ được thay thế trong bản dựng (ví dụ như gulp và gulp-html-replace).

Xem câu hỏi này:

Đối với bước cuối cùng, bạn cũng có thể tải không đồng bộ các ứng dụng dựa trên một tập tin cấu hình:

var injector = Injector.resolveAndCreate([HTTP_PROVIDERS]); 
var http = injector.get(Http); 

http.get('config.json').map(res => res.json()) 
    .subscribe(data => { 
    bootstrap(AppComponent, [ 
     HTTP_PROVIDERS 
     provide('config', { useValue: data }) 
    ]); 
    }); 

Xem câu hỏi này cho biết thêm chi tiết:

+0

Nhưng điều đó có nghĩa là tôi phải sao chép và dán vào đúng cấu hình tùy thuộc vào môi trường. Tôi nghĩ rằng nó sẽ là thanh lịch hơn nếu tôi có một tập tin cấu hình cho mỗi môi trường, đó là ngoài kiểm soát phiên bản và có thể là cá nhân cho mỗi thành viên trong nhóm. Sao chép và dán trước khi xây dựng cũng có vẻ không phải là một ý tưởng tuyệt vời nếu bạn muốn có một dòng chảy tự động và CI. –

+1

Nó sẽ không được sao chép/dán thủ công nhưng được tích hợp bên trong bản dựng của bạn (ví dụ như gulp và gulp-html-replace). Xem câu hỏi này: http: // stackoverflow.com/questions/36285064/how-do-i-actual-deploy-an-angular-2-typescript-systemjs-app/36315060 –

+1

Một cách tiếp cận khác là đẩy mạnh ứng dụng sau khi tải một tệp cấu hình. Tôi cập nhật câu trả lời của tôi cho phù hợp ... –

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