2017-02-28 96 views
1

我正在學習Angular,我有一個帶有返回頁面內容的API的CMS。頁面可以有形式的短代碼,我已經更新了API與組件選擇來取代短角動態組件加載

示例頁面內容看起來就像

<div>bla bla bla </div> 
<app-form [id]="1"></app-form> 

在角我創建FormComponent相應負載的形式,但是當我得到的頁面內容與上述選擇我的錯誤

「應用型」不是一個已知的元素:.....

我做了一些研究,我發現我需要一些動態組件裝載但找不到任何工作根據我的情況的示例,任何一個可以幫助我如何解決這個問題

回答

1

事實上,你將不得不動態創建這些組件。看到這個plunkr的代碼示例:https://plnkr.co/edit/kkM1aR4yPcIqeBhamoDW?p=info

儘管您需要ViewContainer for Angular來知道插入該動態組件的位置。這是行不通的,因爲您無法綁定到innerHTML,然後手動更改innerHTML的代碼。我不確定,但我認爲這會混淆angulars改變檢測。

幾個月前我不得不這樣做,並提出了一個解決方案。我現在要提一下,我不確定現在是否有更好的解決方案來解決這個問題。無論如何,我所做的不是創建動態組件,而是使用* ngIfs創建一些自定義渲染。 讓我解釋一下:你的內容包含標籤。您決定這些標籤的外觀如何。 在我的情況下,我有一個標籤,用戶可以插入任何他想要的地方:[galerie="key_of_gallery"]。 所以內容可能看起來像

some normal text 
<h2>Oh what a nice heading</h2> 
[galerie="summer_gallery"] 
text again 

現在我該如何渲染? 我會得到這樣的

<div> 
    some normal text 
    <h2>Oh what a nice heading</h2> 
</div> 
<galerie [key]="summer_gallery"></galerie> 
<div> 
    text again 
</div> 

所以我創建了創建這個自定義組件:

import { Component, Input } from '@angular/core'; 

@Component({ 
    selector: 'ffam-render-key-value', 
    template: `<div *ngFor="let contentToRender of contentArray"> 
        <div *ngIf="contentToRender.type==='normal'" [innerHTML]="contentToRender.value"> 
        </div> 
        <galerie *ngIf="contentToRender.type==='gallery'" [key]="contentToRender.key"></galerie> 
       </div>` 
}) 
export class NoeRenderKeyValueComponent{ 
    @Input('contentArray') contentArray: any[] = []; 
} 

所有這些組件需要的是將與呈現標籤的數組* ngFor。根據標籤的類型,創建普通的HTML或組件。

該組件可以插入像

<ffam-render-key-value [contentArray]="keyValues['_text'].arrayWithCustomTags"> 
    </ffam-render-key-value> 

爲了得到這個數組的標籤我已經創建了一個功能的服務:

public getArrayWithCustomTags(keyValue): any[] { 
     let arrayWithCustomTags: any[] = []; 
     //check if custom Tag exists in the innerHTML 
     if (keyValue.value.indexOf('[galerie=') !== -1) { 
      //replace double quotes 
      keyValue.value = keyValue.value.replace(/&quot;/g, '"'); 
      //it exists, get array of all tags 
      //regex that matches all [galerie="SOME KEY"] or [someAttribute="some text here"] -> You have to change this regex to fit all your tags 
      let pattern = /(?:(\[galerie=\"[^\"]+\"\]))+/; 
      //split with regexp to get array 
      let arrayOfContents: string[] = keyValue.value.split(new RegExp(pattern, 'gi')); 
      for (let i = 0; i < arrayOfContents.length; i++) { 
       if (typeof arrayOfContents[i] === "undefined") { 
        arrayOfContents.splice(i, 1); 
        i--; 
       } 
       else { 
        let customTagToBeInserted: any = {}; 
        if (arrayOfContents[i].indexOf('[galerie=') !== -1) { 
         //custom tag gallery 
         customTagToBeInserted.type = "gallery"; 
         //get key only 
         customTagToBeInserted.key = arrayOfContents[i].replace("[galerie=\"", "").replace("\"]", ""); 
        } 
        //else if some other attribute or even create a switch() {} 
        else { 
         //insert the normalHtml sanitized 
         customTagToBeInserted.type = "normal"; 
         customTagToBeInserted.value = this.sanitizer.bypassSecurityTrustHtml(arrayOfContents[i]); 
        } 
        arrayWithCustomTags.push(customTagToBeInserted); 
       } 
      } 
     } 
     else { 
      arrayWithCustomTags.push({ type: "normal", value: this.sanitizer.bypassSecurityTrustHtml(keyValue.value)}); 
     } 
     return arrayWithCustomTags; 
    } 

這將創建像數組:

[0]: {type: "normal", value:"SecureHTML"}, 
[1]: {type: "gallery", key:"summer_gallery"}, 
[2]: {type: "normal", value:"SecureHTML"}, 

嗯,我想你明白了。 如果您使用更多標籤創建整個CMS,我會建議創建一個可以輕鬆創建標籤的整個過程(正則表達式等)的函數。 此示例代碼僅適用於一個標籤。

結果是組件在用戶放置它們的位置呈現正確。 我希望這可以幫助你。

順便說一句,如果你有可編輯的鍵值對的用戶,你可能會發現這有幫助:https://github.com/bergben/ng2-ck-editable。這是我使用ck編輯器編輯任何div的一個小模塊。