角度通用:仅用于浏览器的动态导入 [英] angular universal: dynamic imports for browser only

查看:12
本文介绍了角度通用:仅用于浏览器的动态导入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以根据条件导入模块?仅当 angular 2 通用应用在浏览器中呈现但不在服务器中呈现时,才专门导入外部模块.

Is it possible to import a module based on condition? Specificly import external module only if angular 2 universal app being rendered in browser but not in server.

这个问题与一些依赖浏览器功能的 PrimeNG 模块有关,并且只能在浏览器中呈现.在服务器渲染时省略它们会很棒,因为日历和其他组件对于 SEO 来说并不重要.

This question is relevant to some PrimeNG modules that depend on browser features and can be rendered only in browser. It would be great to omit them at server rendering cause calendars and other components are not really important for SEO.

目前,如果关闭服务器渲染,我可以渲染日历组件.但是,当我在 app.module.ts 中包含以下代码并打开服务器呈现时,服务器会在 button.js 中产生错误ReferenceError: Event is not defined".

Currently I can render Calendar component if turn off server rendering. But server produces an error 'ReferenceError: Event is not defined' in button.js when I include this code below in my app.module.ts and turn on server rendering.

import { CalendarModule } from 'primeng/components/calendar/calendar';
@NgModule({
    ...
    imports: [
        ...,
        CalendarModule
    ]
})

angular 提供了一个 isBrowser 条件.

There is a isBrowser condition provided by angular.

import { isBrowser } from 'angular2-universal';

但我不知道如何将其用于条件导入.真的有办法为模块做到这一点吗?

But I don't know how to use it for conditional imports. Is there really a way to do it for modules?

推荐答案

所以有一种方法可以在浏览器中渲染 PrimeNG 组件并在服务器渲染时省略它们.这些问题帮助我开始寻找正确的方向:

So there is a way to render PrimeNG components in browser and omit them while server rendering. Those questions helped me start digging the right direction:

angular-cli:使用环境变量的条件导入

如何有条件地导入 ES6 模块?

在服务器渲染时,我使用模拟组件来渲染一个简单的输入字段并使用相同的选择器p-calendar".我在 app.module 中得到的最终代码.

While server rendering I used mock component that renders a simple input field and uses the same selector 'p-calendar'. The final code I ended up with in my app.module.

...//other imports
import { isBrowser } from 'angular2-universal';

let imports = [
    ... //your modules here
];
let declarations = [
    ... //your declarations here
];

if (isBrowser) {
    let CalendarModule = require('primeng/components/calendar/calendar').CalendarModule;
    imports.push(CalendarModule);
}
else {
    let CalendarMockComponent = require('./components/primeng/calendarmock.component').CalendarMockComponent;
    declarations.push(CalendarMockComponent);
}

@NgModule({
    bootstrap: [AppComponent],
    declarations: declarations,
    providers: [
        ... //your providers here
    ],
    imports: imports
})

要使您的模拟组件支持 [(ngModel)] 绑定,请使用本教程.http://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel

To make your mock component support [(ngModel)] binding use this tutorial. http://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel

import { Component, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => CalendarMockComponent),
    multi: true
};

@Component({
    selector: 'p-calendar',
    template: '<input type="text" class="form-control"/>',
    providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class CalendarMockComponent implements ControlValueAccessor {

    private innerValue: any = '';

    private onTouchedCallback: () => void = () => {};
    private onChangeCallback: (_: any) => void = () => {};

    //From ControlValueAccessor interface
    writeValue(value: any) {
        if (value !== this.innerValue) {
            this.innerValue = value;
        }
    }

    registerOnChange(fn: any) {
        this.onChangeCallback = fn;
    }

    registerOnTouched(fn: any) {
        this.onTouchedCallback = fn;
    }
}

这篇关于角度通用:仅用于浏览器的动态导入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆