• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[GELÖST] Javascript SSE und JSON parsen - Optimierungsideen gesucht

Hallo,

also ich stehe auf den Schlauch und habe echt keine Ahnung, wie ich das angehen soll.

Zum besseren Verständnis hier mal der größte Teil des gesamten Codes:

Code:
<link rel="stylesheet" href="Menu.css">

<script>

var items = {};

function getJSON(url) {
    var resp ;
    var xmlHttp ;

    resp  = '' ;
    xmlHttp = new XMLHttpRequest();

    if(xmlHttp != null)
    {
        xmlHttp.open( "GET", url, false );
        xmlHttp.send( null );
        resp = xmlHttp.responseText;
    }

    return resp ;
}



function initi(){
	
	var gjson;
	
	gjson = getJSON('http://192.168.178.52:8080/rest/items?recursive=false') ;
	obj=JSON.parse(gjson);
	obj.forEach(function(entry) {

		var name = entry.name;
		items[name] = {value:entry.state};
		console.log(name, items[name].value);
		
					});		
}

initi();
console.log("Werte sind initialisiert");






 // Event-Stream
 
 
 
 var eventSource = new EventSource("http://192.168.178.52:8080/rest/events");

eventSource.addEventListener('message', function(eventPayload){
	var event = JSON.parse(eventPayload.data);
	if (event.type === "ItemStateEvent"){  
		var name = event.topic.split('/')[2];
		items[name] = JSON.parse(event.payload);
		console.log(name, items[name].value);

	}
	
	console.log("events werden empfangen");
	console.log(name, items[name].value);
});
   



</script>


		
		<div class="flex-1">
			<ul class="lamps__list">
				
				<li class="lamps__item  lamps__total">
					<h2 class="lamps__count" id="id1"><script type="text/javascript">document.write(items['FEG_HZ_Soll'].value)</script></h2>
					<p class="lamps__description">Total Lamps</p>
				</li>
				
				<li class="lamps__item  lamps__active">
					<h2 class="lamps__count" id="id2"><script type="text/javascript">document.write(items['FEG_HZ_Ist'].value)</script></h2>
					<p class="lamps__description">Active Lamps</p>
				</li>
				
			</ul>	

</div>

Ziel ist es jetzt, dass immer wenn Events empfangen werden die die beiden Variablen aktualisiert werden.

Irgendwie bekomme ich es aber nicht hin :-(
 
Also document.write() solltest du schleunigst aus deinem Gedächtnis streichen!

Viel sicherer ist
Code:
document.getElementById(id).textContent = value;
 
Ich würde da nicht mit einem synchronen XHR arbeiten und document.write() ist auch eher suboptimal (und v.a. für das Aktualisieren komplett ungeeignet)... aber das nur am Rande. Prinzipiell hast du ja für jedes Item schon eine ID: den Namen, den du aus der Schnittstelle bekommst. Den kannst du direkt so weiterverwenden. Wenn du dann ein Event bekommst, holst du dir per document.getElementById() die entsprechende Node und schreibst mit .textContent den Inhalt da rein. Wenn du noch die Initialisierung ähnlich machst, brauchst du die globale Variable items dann auch gar nicht mehr.

Zu document.write:
http://www.w3.org/html/wg/drafts/html/CR/webappapis.html#dynamic-markup-insertion schrieb:
This method has very idiosyncratic behavior. In some cases, this method can affect the state of the HTML parser while the parser is running, resulting in a DOM that does not correspond to the source of the document (e.g. if the string written is the string "<plaintext>" or "<!--"). In other cases, the call can clear the current page first, as if document.open( ) had been called. In yet more cases, the method is simply ignored, or throws an exception. To make matters worse, the exact behavior of this method can in some cases be dependent on network latency, which can lead to failures that are very hard to debug. For all these reasons, use of this method is strongly discouraged.
 
Du solltest deinen Code nach einem einheitlichen Schema formatieren.
Am Zeilenanfang nicht Leerzeichen und Tabulatoren mischen.
Öffnende geschweifte Klammer { mal in der selben Zeile und mal in der nächsten Zeile.
Parameter mal mit einfachen Anführungszeichen ' und mal mit dopelten Anführungszeichen ".
Überflüssige Leerzeichen vor dem Semikolon ; am Zeilenende var resp ; solltest du entfernen: var resp;
Öffnendes JavaScript-Tag mal mit type-Attribut <script type="text/javascript"> und mal ohne <script>.

Auf document.write() wurdest du ja schon hingewiesen.

Wenn du Variablen mittels var initialisierst, kannst du auch gleich einen Wert zuweisen, bzw. auch in einem Block (Komma separiert) definieren bzw. zuweisen:
Code:
	var resp;
	var xmlHttp;

	resp = '';
	xmlHttp = new XMLHttpRequest();
Code:
	var resp = '';
	var xmlHttp = new XMLHttpRequest();
Code:
	var resp = '',
		xmlHttp = new XMLHttpRequest();


Die Funktion initi würde ich lieber aufrufen wenn das HTML (innerhalb der body-Tags) geladen ist. Also entweder mit window.onload = initi; ober direkt vor dem schließenden body-Tag mittels script-Tag:
HTML:
		...
	<script>
		initi();
	</script>
</body>

Anschließend eine Funktion, z.B. updateValues aufrufen, welche deine Werte im HTML aktualisiert. Diese Funktion kannst du dann in der Funktion initi, sowie in deiner Event-Stream-Rückgabefunktion aufrufen.


Die Initialisierung deines Event-Streams würde ich dann natürlich auch in die Funktion initi reinpacken.

In der Funktion initi kannst du dir die Variable name auch sparen:
Code:
function initi(){
	var gjson = getJSON('http://192.168.178.52:8080/rest/items?recursive=false'),
		eventSource = new EventSource('http://192.168.178.52:8080/rest/events');
	
	obj = JSON.parse(gjson);
	obj.forEach(function (entry) {
		items[entry.name] = {value:entry.state};
		console.log(entry.name, items[entry.name].value);
	});
	console.log('Werte sind initialisiert');
	updateValues();

    // Event-Stream
    eventSource.addEventListener('message', function (eventPayload) {
        var event = JSON.parse(eventPayload.data);
        if (event.type === 'ItemStateEvent') {  
            var name = event.topic.split('/')[2];
            items[name] = JSON.parse(event.payload);
            console.log(name, items[name].value);
        }
        
        console.log('events werden empfangen');
        console.log(name, items[name].value);
		updateValues();
    });
}

Da die items (FEG_HZ_Soll, FEG_HZ_Ist...) anscheinend sowieso "einmalig" sind, würde ich diese als id in deinem HTML verwenden:
HTML:
		<div class="flex-1">
			<ul class="lamps__list">
				
				<li class="lamps__item  lamps__total">
					<h2 class="lamps__count" id="FEG_HZ_Soll"></h2>
					<p class="lamps__description">Total Lamps</p>
				</li>
				
				<li class="lamps__item  lamps__active">
					<h2 class="lamps__count" id="FEG_HZ_Ist"></h2>
					<p class="lamps__description">Active Lamps</p>
				</li>
				
			</ul>

</div>
und dann in der Funktion updateValues benutzen:
Code:
function updateValues() {
	for (var name in items) {
		if (items.hasOwnProperty(name)) {
			document.getElementById(name).textContent = items[name].value;
		}
	}
	console.log('Werte wurden aktualisiert');
}
 
Vielen lieben Dank zusammen. Ihr habt mir wirklich total geholfen. Ich kämpfe noch mit ein paar null werten aus der Schnittstelle - aber das bekomme ich hin.

Vielen Dank Euch allen.
 
Zurück
Oben