2017-01-04 4 views
3

У меня есть проект сгенерированный angular-cli, который я хотел бы использовать с бэкэндом deployd. Deployd предоставляет скрипт для доступа к его API, который может быть загружен с http://<deployd-host>/dpd.js. Это создает глобальный объект dpd, который может получить доступ к API из глобального контекста javascript (например, из консоли инструментов Chrome dev).Обтекание внешнего скрипта в службе Angular2

Я хотел бы обернуть это в службе Angular2, чтобы я мог ввести макет для тестирования и т. Д. Задачами являются загрузка скрипта из URL-адреса, а затем получение доступа к глобальному объекту dpd. Я посмотрел на this SO сообщение, но не смог получить принятый ответ на работу. Если я добавлю скрипт вручную к объекту document, я не могу получить доступ к объекту dpd по адресу window.

Кроме того, URL-адрес, с которого загружен сценарий, будет отличаться в зависимости от окружения, например. http://localhost:3000/dpd.js для местного разработчика, http://dev.example.com/dpd.js для постановки и http://www.example.com/dpd.js для производства. Поэтому в идеале я смог бы настроить это и в сервисе.

Ищете что-то вроде ниже, чтобы работать.

@Injectable() 
export class DpdService { 
    constructor() { 
    if (getEnvironmentSomeHow() == 'development') { 
     loadScriptFrom("http://localhost:3000/dpd.js"); 
    } else { 
     loadScriptFrom("http://dev.example.com/dpd.js"); 
    } 
    dpd = window.dpd; 
    } 

    public session(): Observable<Session> { 
    return Observable.fromPromise(dpd.sessions.get()); 
    } 
} 
+0

Вы можете поделиться некоторым кодом –

+0

Возможный дубликат: http://stackoverflow.com/questions/39942118/how-to-inject-different-service-based-on-certain-build-environment-in-angular2/39942256 # 39942256 Очень подробное объяснение с кодом – Karl

+0

И в чем проблема, связанная с подходом, который вы указали в вопросе? – estus

ответ

1

Условия использования полностью зависят от выбора разработчика. Они могут быть условно включены в файлы TS, которые зависят от переменной среды Node. Это может быть единственный файл, который определяет Угловые провайдеры в зависимости от глобальной переменной на стороне клиента (вероятно, с Webpack DefinePlugin или EnvironmentPlugin, см., Например, angular2-webpack-starter). В своей самой простой форме это просто на стороне клиента глобальной ENV переменной, все решения принимаются на месте - она ​​даже может быть установлен в HTML с серверной стороны шаблонам:

<script> 
    window.ENV = <% SERVER_SIDE_ENV_VARIABLE %> 
</script> 

В связи с тем, что сценарий должны быть загружены при инициализации приложения, он должен быть загружен в APP_INITIALIZER multiprovider:

... 
import {APP_INITIALIZER} from '@angular/core' 
import {DOCUMENT} from '@angular/platform-browser' 

@Injectable() 
export class DpdService { 
    dpd: any; 

    constructor(@Inject(DOCUMENT) document: Document) {} 

    load() { 
    const srcBase = window.ENV === 'dev' 
     ? 'http://localhost:3000/' 
     : 'http://dev.example.com/'; 

    const script = this.document.createElement('script'); 
    this.document.body.appendChild(script); 

    return new Promise((resolve, reject) => { 
     script.onload = resolve; 
     script.onerror = reject; 
     script.async = true; 
     script.src = srcBase + 'dpd.js'; 
    }).then(() => { 
     this.dpd = window.dpd; 
    }); 
    } 

    session(): Observable<Session> { 
    return Observable.fromPromise(this.dpd.sessions.get()); 
    } 
} 

export function dpdAppInitializerFactory(dpdService: DpdService) { 
    return() => dpdService.load(); 
} 

... 
providers: [ 
    DpdService, 
    { 
    provide: APP_INITIALIZER, 
    useFactory: dpdAppInitializerFactory, 
    deps: [DpdService], 
    multi: true 
    } 
], 

...

в тот момент, когда приложение инициализируется, обещание от load метода выполняется и dpd Недвижимость установлена.

+0

Это отлично работает. Пара вещей ... 'DpdService.load()' должен быть 'dpdService.load()'. Кроме того, после этого я получаю сообщение об ошибке «Ошибка обнаружения значений символов». Вызов функций не поддерживается. Рассмотрите возможность замены функции или лямбда ссылкой на экспортированную функцию (позиция 23:19 в исходном файле .ts), разрешающий символ AppModule' –

+0

Что касается среды, то это использование 'углового-cli', который должен управлять средой. –

+0

Таким образом, ошибка, кажется, проблема с 'aot' ... не должна иметь ничего общего с вашим решением. –