1

をレンダリングし、テキストエリアの参照を取得にReferenceError:ナビゲータは、サーバー側では、私は私の角度4サーバー側のレンダリングアプリケーションでsimpleMDEエディタを使用しています

@ViewChild('simpleMDE') textarea : ElementRef; 

を使用してngAfterViewInitでそれを初期化してangular4に定義されていません()

この

<textarea id="simpleMDE" #simpleMDE></textarea> 
のようにテキストエリアを使用して午前中のテンプレートで
this.simplemde = new SimpleMDE(
     { 
      element: this.textarea.nativeElement.value, 
     }) 

サーバを起動している間に、スローエラーが発生しました。

projectpath\node_modules\codemirror\lib\codemirror.js:11 
     typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 
                       ^
ReferenceError: navigator is not defined 
    at projectpath\node_modules\codemirror\lib\codemirror.js:18:17 

何かお伝えください。 角度ユニバーサルドキュメントに

ウィンドウ、ドキュメント、ナビゲーター、および他のブラウザの種類に述べたようにGitHub Repo

答えて

2

- サーバー上に存在しない - (たとえばjQueryの)それらを使用していますので、それらを使用して、または任意のライブラリをします動作しない

これらを使用する必要がある場合は、それらをクライアントに限定し、状況に応じてラップすることを検討してください。 PLATFORM_IDトークンを使用して挿入されたObjectを使用して、現在のプラットフォームがブラウザかサーバーかを確認できます。

var userAgent = navigator.userAgent; 
var platform = navigator.platform; 

は、そのコード

if(navigator){ 
    var userAgent = navigator.userAgent; 
    var platform = navigator.platform; 
}else{ 
var userAgent="server"; 
var platform="server"; 
} 

PSを操作しようと、エラーがcodemirror.jsから来ている行を次のように :

import { PLATFORM_ID } from '@angular/core'; 
import { isPlatformBrowser, isPlatformServer } from '@angular/common'; 

constructor(@Inject(PLATFORM_ID) private platformId: Object) { ... } 

ngOnInit() { 
    if (isPlatformBrowser(this.platformId)) { 
     // Client only code. 
     ... 
    } 
    if (isPlatformServer(this.platformId)) { 
    // Server only code. 
    ... 
    } 
} 

は、ライブラリ:(

編集を操作する必要があります:影響がどのようになるかはっきりしない:D。

+0

コード内のどこでも手動で使用しませんでしたが、simpleMDEのテキストエディタは内部でそれを使用しています。 私は自分のマシンに戻ってすぐにあなたのソリューションを試してみます。 ありがとうございました.... –

+0

@PraveenRana問題の解決に役立つかどうかわからない、編集済みの回答をご覧ください。 –

+0

さて、Parth。私はこのコードをテストし、これがうまくいくかどうかを知らせます。 夕方にのみテストできます。 –

1

js/tsファイルに次のようなコードがあると思います。

import CodeMirror from 'codemirror'; 

@Parth Ghiya、navigatorによって答えとしては、ブラウザのみでsurpportedされ、これはエラーにつながります。

サーバーレンダリングをサポートしようとしますが、あなたがこのようにコードの何らかの変化(怠惰が必要)を作ることができます:ここでは

// just before places where are using codemirror 
const CodeMirror = require('codemirror'); 
require('codemirror/addon/hint/show-hint'); 

CodeMirror(...) 
+0

あなたはリポジトリを見てみることができますかhttps://github.com/ranavc32/SimpleMDE-角度ユニバーサル –

+0

@PraveenRana 'simplemde'の依存関係は' codemirror'を使っているようですが、サーバレンダリングの問題を見過ごすことはできませんでした。それでも 'angular-universal'で使用したいのであれば、' simplemde'ライブラリに答えたような変更を加えるべきです。 – Pengyy

+0

リポジトリにあなたが言っている変更に応じてプルリクエストをすることができますか?私はどこに何を正確に変更する必要があるかわからないので、多くの義務があります。 ありがとうございます。 –

0

が、私はこのみかん問題を処理する方法です。 私には、サーバレンダリングはSEO目的のためだけです。そして、codemirrorのようなものはSEOで何もしません。したがって、私のアプローチは「サーバー側ではレンダリングしない」ことです。

enter image description hereref

基本的な構造は、上の図のようです。

2つのブートファイルがあります.1つはサーバーレンダリング用、もう1つはクライアントレンダリング用です。

したがって、実際には、ブートファイルごとに異なるアプリケーションモジュールを使用できます。

サーバーレンダリングのアプリケーションモジュールでは、模擬コンポーネントを使用して、ブラウザオブジェクトを使用するコンポーネントを置き換えて、クライアント側に実際のコンポーネントを使用できます。

この方法では、サーバーレンダリングで問題のあるコンポーネントについて心配する必要はありません。

もう1つの解決策は、webpackを使用してこれらのブラウザオブジェクトを処理することです。個人的にこのref

module: { 
    rules: [ 
    { 
     test: /@angular(\\|\/)material/, use: "imports-loader?window=>global,CSS=>null,navigator=>{get userAgent(){return Zone.current.get('req')['headers']['user-agent'];}}" 
    } 
    ] 
} 

よう

何か、私は最初のソリューションを好みます。 2番目は私にとってはちょっとハッキーで、サーバー側でSEOと関係のないコンポーネントをレンダリングしても実際に私たちに利益をもたらすわけではありません。

関連する問題