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

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

问题描述

是否可以根据条件导入模块?具体来说,仅当在浏览器中而不是在服务器中渲染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.

当前,如果关闭服务器渲染,则可以渲染Calendar组件.但是,当我在app.module.ts中包含以下代码并打开服务器渲染时,服务器在button.js中产生错误"ReferenceError:未定义事件".

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天全站免登陆