2017-10-02 4 views
0

Ich habe eine App, wo ein Seitengenerator eine Startseite erstellt, die in der Datenbank gespeichert ist. Die gespeicherte Information ist nur die outerHTML des DOM-Objekts. Um die Bearbeitungsfunktion zu erstellen, brauche ich eine inverse Funktion, die das DOM-Objekt aus den HTML-Informationen neu erstellt. Leider führt die Zuordnung der entschlüsselten Informationen zum Abschnitt outerHTML zu nichts, da die Änderungen im DOM-Objekt ignoriert werden.So erstellen Sie aus einem HTML-Text ein DOM-Objekt

Meine Frage: Wie kann ich ein DOM-Objekt aus gespeicherten OuterHTML-Informationen neu erstellen? Wenn das unmöglich ist, was wäre der richtige Weg, um so etwas zu tun?

BEARBEITEN Vielen Dank für Ihre Antwort! Hier sind einige Codeschnipsel, die zeigen, was ich mache. Der Prototyp MainWidget erhält Informationen von der HTML-Seite & möchte die Informationen zuweisen. Benutzte Funktionen sind Teil eines anderen Objekts (Prototyp) namens Widgets.

var asserts = new Asserts(); 
var calls = new Calls(); 
var constants = new MainConst(); 
var strings = new Strings(); 
var widgets = new MainWidget(); 

MainWidget.method('assign2Widget', function (call, label, value, isValid) { 
    isValid = toBoolean(isValid), value = strings.toString(value); 

    if (calls.isValid(call) && strings.hasMinimalLength(label, 2)) { 
     var section = (!label.includes('Builder') // A marker, not an element! 
         && !label.includes(constants.NewsTicker)) 
      ? widgets.getSgSectionByLabel(document, label) 
      : null; 
     value = strings.decode(decodeURIComponent(value));  //<<<< Code decoded from DB 

     if (asserts.isObject(section)) { 
      section.outerHTML = value; 
     } else if (label.includes(constants.Elements)) { 
      if (asserts.isValid(infos.Elements) && infos.Elements.length > 0) { 
       // HERE, THE CODE FROM DB SHOULD BE ADDED TO WIDGET. 
       // The "label" gives the label of the widget, and the "value" is 
       // what is to be assigned to. 
      } 
     } else if (label.includes(constants.NewsTicker)) { 
      […] 
     } 
     […] 
}); 

Widget.method('getElementTypeByLabel', function (thing, elementType, label) { 
    if (asserts.isObject(thing) 
     && strings.hasMinimalLength(elementType, 2) 
     && strings.hasMinimalLength(label, 2)) { 

     var element, elements = document.getElementsByTagName(elementType); 

     if (asserts.isValid(elements) 
      && asserts.isDefined(elements.length) && elements.length === 0) { 

      elements = thing.children; 
     } 
     for (var i = 0; asserts.isDefined(elements.length) && i < elements.length; i++) { 
      element = elements*; 

      if (element.getAttribute !== null) { 
       var labelName = element.getAttribute(constants.label); 

       if (label === labelName && element !== null) { 
        return element; 
       } 
      } else { 
       return null; 
      } 
     } 
     // If the element was not found, search recursively the elements! 
     for (var i = 0; asserts.isDefined(elements.length) && i < elements.length; i++) { 
      return this.getElementTypeByLabel(elements*, elementType, label); 
     } 
    } else { 
     // Error! //messages.invalidFunctionCall(functionName); 
    } 
    return null; 
}); 

Widget.method('getSgSectionByLabel', function (element, label) { 
    return this.getElementTypeByLabel(element, 'sg-section', label); 
}); 

EDIT 2: Früher habe ich nur die in den sg-section vorgenommenen Änderungen den Inhalt neu zu erstellen, wenn eine vorhandene Seite bearbeiten.

MainWidget.js: 
[…] 
MainWidget.method('assign2Widget', function (call, label, value, isValid) { 
    isValid = toBoolean(isValid), value = strings.toString(value); 

    if (calls.isValid(call) && strings.hasMinimalLength(label, 2)) { 
     var section = (!label.includes('Builder') // A marker, not an element! 
         && !label.includes(constants.NewsTicker)) 
      ? widgets.getSgSectionByLabel(document, label) 
      : null; 
     value = strings.decode(decodeURIComponent(value)); 

     if (asserts.isObject(section)) { 
      section.outerHTML = value; 
     } else if (label.includes(constants.Elements)) { 
      if (asserts.isString(value) && value.includes(LeftBracket)) { 
       value = arrays.toArray(value); //value.replace(LeftBracket, '').split(RightBracket); 
      } 
      if (arrays.isArray(value)) { 
       for (var i = 0; i < value.length; i++) { 
        infos.insertGridItem(value[i]); 
       } 
      } 
      […] 

MainInfos.js: 
[…] 
function MainInfos() { 
    this.Elements;      // Object for startGridGenerator 
    this.insertGridItem;    // Function of startGridGenerator 
    this.PrototypeName = 'MainInfos'; 
} 

MainInfos.inherits(Infos); 

MainWidget.method('assign2Widget', function (call, label, value, isValid) { 
    isValid = toBoolean(isValid), value = strings.toString(value); 

    if (calls.isValid(call) && strings.hasMinimalLength(label, 2)) { 
     var section = (!label.includes('Builder') // A marker, not an element! 
         && !label.includes(constants.NewsTicker)) 
      ? widgets.getSgSectionByLabel(document, label) 
      : null; 
     value = strings.decode(decodeURIComponent(value)); 

     if (asserts.isObject(section)) { 
      section.outerHTML = value; 
     } else if (label.includes(constants.Elements)) { 
      if (asserts.isString(value) && value.includes(LeftBracket)) { 
       value = arrays.toArray(value); //value.replace(LeftBracket, '').split(RightBracket); 
      } 
      if (arrays.isArray(value)) { 
       for (var i = 0; i < value.length; i++) { 
        infos.insertGridItem(value[i]); 
       } 
      } 
     } else if (label.includes(constants.NewsTicker)) { 
      […] 
     } 
}); 

startGridGenerator.js: 
[…] 
(function() { 
    var moduleName = 'ivmGridBuilder'; 

    var controllerName = moduleName + Controller; 

    angular.module(moduleName, [ 
     'ionic', 
     'ui.sortable', 
     'ivmColorpicker', 
     'ivmIconpicker' 
    ]) 
     .controller(controllerName, function ($scope, 
               $ionicScrollDelegate, 
               $ionicModal, 
               $sce, 
               CommunicationService) { 
      […] 
      /** 
      * Inserts an existing grid item to the item's array 
      * 
      * @param item 
      */ 
      $scope.insertGridItem = function (item) { 
       if (asserts.isObject(item)) { 
        $scope.items.push(item); 
        infos.Elements.push(item); 
        $ionicScrollDelegate.resize() 
       } else { 
        // First call with no valid item & "remember" this function 
        // by having a link to in in object MainInfos! 
        infos.insertGridItem = $scope.insertGridItem; 
       } 
      }; 

Antwort

1

Die Lösung sollte so sein, erhalten Sie eine HTML-Zeichenfolge mit dem Inhalt. Dann verwenden Sie die $sce.trustAsHtml(); und zuweisen, um eine Scope-Variable, die den HTML-Code sicher ist, dann können Sie den HTML-Code, der die Direktive ng-bind-html hat, den HTML-String als tatsächlichen HTML-Code verwenden.

Hier ist ein Arbeitsbeispiel für das gleiche.

var app = angular.module("angularApp", []); 
 
app.controller("appController", function($scope, $sce) { 
 
    $scope.content = "This text is <em>html capable</em> meaning you can have <a href=\"#\">all</a> sorts <b>of</b> html in here."; 
 
    $scope.output = $sce.trustAsHtml($scope.content); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<h2>Rendering HTML with angularJS</h2> 
 
<div ng-app="angularApp" ng-controller="appController"> 
 
    <div ng-bind-html="output"></div> 
 
</div>

Eine weitere Option ist ng-sanitize zu verwenden.

Wenn Sie ng-sanitize verwenden - Eingaben werden bereinigt, indem der HTML-Code in Token zerlegt wird. Alle sicheren Token (von einer Whitelist) werden dann seriell in eine korrekt gematchte HTML-Zeichenfolge zurückversetzt. Dies bedeutet, dass keine unsichere Eingabe in die zurückgegebene Zeichenfolge gelangen kann.

Verweisen Sie die folgende Frage für eine ausführlichere Erklärung.

SO Answer


var app = angular.module("angularApp", ['ngSanitize']); 
 
app.controller("appController", function($scope) { 
 
    $scope.content = "This text is <em>html capable</em> meaning you can have <a href=\"#\">all</a> sorts <b>of</b> html in here."; 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.6/angular.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.6/angular-sanitize.min.js"></script> 
 
<h2>Rendering HTML with angularJS</h2> 
 
<div ng-app="angularApp" ng-controller="appController"> 
 
    <div ng-bind-html="content"></div> 
 
</div>

Wie in dem obigen Beispiel gesehen gibt es keine Notwendigkeit für den Aufruf $sce.trustAsHtml(); da ngSanitize automatisch darum kümmern.

Lassen Sie mich wissen, ob dieser Ansatz Ihnen hilft oder wenn Sie Probleme mit dem gleichen haben!

1

Sie DOMParser() verwenden können, ein #document oder <template> Element zu schaffen, eine #document-fragment aus einem String

const parser = new DOMParser(); 
const doc = parser.parseFromString(/* outerHTML */, "text/html"); 
+0

Danke! Ich werde versuchen, ob ich das verwenden kann, um das leere 'sg-section'-Objekt im DOM durch die gespeicherte' sg-section' 'outerHTML'-Information zu ersetzen. – Sae1962

1

Sie die Zeichenfolge in eine versteckte Div in Seite hinzufügen zu erstellen, dann bekommen mit JavaScript, um die Elemente, die du von diesem Div. Wie in diesem Code:

var str ='abc 123<div id="test">coursesweb.net</div><span class="cls">some text</span>'; 
document.querySelector('body').insertAdjacentHTML('beforeend', '<div style="display:none;">'+str+'</div>'); 
var ob_test = document.getElementById('test'); 
alert(ob_test.innerHTML); 
+0

Vielen Dank für Ihre Antwort! Ich habe sogenannte "SG-Section" -Objekte, die vom Seitengenerator erstellt werden, die ich in der Datenbank speichere. Ist es möglich, das vorhandene leere Objekt mit dem in der Datenbank zu ändern, indem man den Trick eines versteckten Elements benutzt? – Sae1962

+0

Versuchen Sie Folgendes: 'document.querySelector ('# sg-section_id'). OuterHTML = 'html string';'. Oder wenn sg-section ein Objekt in JS ist: 'sg-section.outerHTML = 'html string';' – CoursesWeb

+0

Danke für deine Antworten! Ich dachte, ob es besser ist, eine ganze 'sg-Section' oder nur den geänderten Inhalt zu speichern und könnte letzteres verwenden, so dass ich nur das JavaScript-Objekt gespeichert habe. – Sae1962

Verwandte Themen