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

Konstruktor und Pfadangeaben aus externer Datei lesen

Hallo zusammen,

würde gerne meinen alten Thread wieder aufnehmen - da es jetzt in der Sache weitergeht :rolleyes:

Kurze Beschreibung: Ich lade ein JSON in meine App.
JSON:
Code:
[{   "id":Label-1",
            "name":"Label 1", 
            "kn": true,
            [COLOR="#008000"]"const": [
                {
                    [COLOR="#FF0000"]"text": "dataService.getText(0)", // Problemkind, das sollte am Ende so aussehen->   text: dataService.getText(0)[/COLOR]
                    "font": "sourcesanspro",
                    "align": "txt.Align.CENTER_MIDDLE",
                    "x": 90,
                    ...
                },[/COLOR]
            ...
}, ...]

Der Inhalt von const wird beim Laden der JSON-Datei in eine Variable constructor gesteckt, die ich später beim Erstellen eines Objekts verwende. Der Code beim Erstellen des Objekts sieht so aus:

Code:
[COLOR="#FF0000"]// objekt erstellung hard-coded -> [/COLOR]

textArray.push(new txt.CharacterText(
           {
                [COLOR="#008000"]text: dataService.getText(0), [COLOR="#FF0000"]// das wird in meiner Variante als text: "dataService.getText(0)" ausgegeben und nicht als text: dataService.getText(0)[/COLOR] [/COLOR] 
                font: 'sourcesanspro',
                align: txt.Align.CENTER_MIDDLE,
                x: 90,
                ...
            }

));

[COLOR="#FF0000"]// ich setzt constructor als Objekt ein ->[/COLOR]

textArray.push(new txt.CharacterText( [COLOR="#008000"]constructor[/COLOR] )); // funktioniert - bis auf das Problemkind

Das Problem bei der Sache ist dass der Wert "dataService.getText(0)" aus dem JSON als String übernommen wird.
Sollte aber als Funktion dataService.getText(0) eingefügt werden, welche die sich den Text aus einem Service holt...

Perfekt wäre wenn man Literal-Schreibweise in JSON intergrieren könnte...hmmm

Falls jemand versteht was ich meine - freue mich auf jeden Hinweis :)
 
Zuletzt bearbeitet:
Du kannst in JSON keine Funktionsaufrufe platzieren, denn JSON ist kein JavaScript, sondern ein Datenformat. Dass du das versuchst deutet auf Fehldesign hin. Wieso speicherst du im JSON nicht einfach den Index "0" in einem Feld und rufst diesen später über deinen DataService ab? (dataService.getText(json.index)).
 
Zuletzt bearbeitet:
Dass das zwei Paar Schuhe sind war mir schon bewußt. Wenn man noch frisch in der Materie ist geht man immer ein wenig naiver an die Sache ran...nach dem Motto: warum groß coden, wenn ich das komplett ausm JSON lade :rolleyes:
Ich lass es jetzt kompett ausm JSON raus und füge-> text : dataService.getText(i) jeweils während des Ladens hinzu.
 
Zuletzt bearbeitet:
Du kannst in JSON keine Funktionsaufrufe platzieren, denn JSON ist kein JavaScript, sondern ein Datenformat. Dass du das versuchst deutet auf Fehldesign hin.

Ja das mit dem Fehldesign stimmt und lässt sich jetzt auch nicht mehr "überbrücken" weil immer mehr nicht so funktioniert wie es soll...wäääää

Was würdest Du denn für ein Format fürs Laden empfehlen ? Das Laden ist ein muss, da hier datumabhängige Dateien geladen werden. Ebenso ein Muss ist ein Array, gefüllt mit mehreren Objekten wie so eines:
Code:
{
                x: 0.0000,
                y: 0.0000,
                flipped: false,
                lineHeight: 10,
                singleLine: true,
                autoReduce: true,
                font: 'lobster',
                size: 60,
                strokeColor: '#000',
                strokeWidth: 1,
                fillColor: '#fff',
                valign: txt.VerticalAlign.Bottom,
                start: -52.359875,
                end: -575.958625,
                align: txt.PathAlign.Center,
                [COLOR="#008000"]path: circle(250, 250, 200)[/COLOR], // wichtig dass diese funktion aufgerufen wird
                debug: true,
                tracking: 0
            }

Wichtig dabei ist dass die circle() Funktion aufgerufen wird bzw generell bestimmt Funktionen mit unterschiedlichen Parametern aufgerufen werden können.
 
Zuletzt bearbeitet:
Habe mal versucht hier in Plunker ein kleines Bespiel zu machen...hier lade ich jetzt eine externe Javascript Datei. Aber irgendwie krieg ichs nicht gebacken auf das geladene Objekt in extern.js zuzugreifen?

Lade die externe JS so:
Code:
function loadJS() {
    js2load = "extern.js";
    return $http({
      method: 'GET',
      url: js2load
    });

...

loadJS()
    .then(function(event) {
 
      console.log("then " + Object.keys(event)); // = data,status,headers,config,statusText
      console.log("then " + event.data); // event.data = undefined ??
    })

...

Externe js:

var geladen = {
  text: 'Hallo',
  zahl: 10,
  path: circle(250, 250, 200)
};


Hab schon versucht in der aber ohne Erfolg - vielleicht kann mir hier ja jemand auf die Sprünge helfen :)
 
Ich kann dein Problem nicht reproduzieren. In event.data ist der Inhalt der JS-Datei enthalten.
Hi!
Danke für die Mühe - jetzt geht's hier auch, echt seltsam.

Absolute Anfägersache, aber ich weiß ehrlich gesagt nich so recht wie ich dann z.B auf den Wert von zahl auslese. Wenn ich typeof event.data checke dann erhalte ich: string und somit sind doch dann die Objekteigenschaften futsch, oder?
 
Zuletzt bearbeitet:
AJAX liefert dir den Inhalt der nachgefragten Datei immer als String - als was denn sonst...?

Du könntest jetzt diesen String durch eval jagen, aber das würde ich dir nicht raten. Warum willst du da unbedingt einen Funktionsaufruf reinpacken? Ich kann da rckd nur zustimmen.
 
Naja..Hauptgrund ist eigentlich weil ich sonst nicht weiß wie ichs machen soll.

Das geladene Objekt möchte ich bei jedem Neuzeichnen des Canvas-Objekts verwenden.
Bisher hab ichs als JSON eingelesen und Probleme gibt's bei den Eigenschaften: text: dataService.getText(0) und path: circle(x,y,r)

Das mit text: dataService.getText(0) hab ich wie im Code nach bestem Wissen und Gewissen gelöst - wobei ich hier doch ein wenig Bauchschmerzen habe

Die initCanvas() sieht so aus:

Code:
function initCanvas() { 

            canvas = angular.element(document.getElementById('my-canvas'));
            stage = new createjs.Stage(canvas[0]);

            imageObject = new Image();
            imageObject = dataService.getImage();
            image = new createjs.Bitmap(imageObject);

            textArray = [];

[COLOR="#008000"]            constArray = dataService.getConstructor(); // [COLOR="#FF0000"]Holt sich das geladene Objekt aus dataService[/COLOR]
            
            constArray[0].text = dataService.getText(0); // [COLOR="#FF0000"]habe auch versucht schon während des Ladens die Funktion dataService.getText(i) zuzuweisen[/COLOR]
            constArray[1].text = dataService.getText(1); // [COLOR="#FF0000"]hat aber nicht funktioniert[/COLOR]
            constArray[2].text = dataService.getText(2); // [COLOR="#FF0000"]da zum Zeitpunkt des Ladens dataService.getText(i) noch nicht vorhanden[/COLOR]
            constArray[3].text = dataService.getText(3); // [COLOR="#FF0000"]-- vielleicht doch machbar ?[/COLOR] [/COLOR]
     
            textArray.push(new txt.CharacterText( constArray[0] )); [COLOR="#008000"]// <- so ist's geplant..funktioniert , aber nur wenn kein path vorhanden ist[/COLOR]

            // so sieht der Aufruf "normal" aus ->
            textArray.push( new txt.PathText({
              text: dataService.getText(1),
                ...
                [COLOR="#008000"]path: circle(250, 250, 200), // berechnet kreis im MoveTo - Format[/COLOR]
                ...
            }));

Von textArray.push habe ich 4 Stück im Canvas - und initCanvas() wird jedesmal aufgerufen sobald sich ein Eingabetext ändert = sehr häufig.

Und hier dachte ich eben ob es nicht "performater" ist, statt text: dataService.getText(i) und path: circle(x,y,r) jedesmal aufs neue innnerhalb initCanvas() zu ändern, das Ganze gleich in die externe Datei zu packen.

Ja..und nun steht ich hier


P.S.
Wobei hier während des Schreibens schon mal eingefallen ist - ich könnte ja die Werte von path:circle(x,y,r) für jedes Objekt vorberechnen und ins JSON schreiben! Zwar ein wenig Aufwand vorab - aber damit wäre zumindest die Problematik mit der Funktion nicht mehr da ?!?
 
Zuletzt bearbeitet:
Ich würde da eine lazy computation verwenden. Also du schreibst in das JSON anstatt des Textes und des Pfades Objekte rein, die du dann beim ersten Zeichnen ersetzt und bei allen anderen Zeichenvorgängen hast du dann schon die richtigen Daten.

Also in etwa so etwas:
Code:
{
  "text": {"type": "getText", "index": 0},
  "zahl": 10,
  "path": {"type": "circle", "x": 250, "y": 250, "r": 200}
};
und dann prüfst du in der initCanvas, ob .text bzw. .path ein String ist. Und wenn nicht, befüllst du die Eigenschaften entsprechend der Objekte.
 
Hey, danke für den Anstoß!

Werd mich gleich dran setzen wenn es die Zeit zulässt.. muss erst mit meinem richtigen Job ( 3D Zeugs ) nen spontanen Stressauftrag fertig machen :)
 
Zuletzt bearbeitet:
Ich habe das jetzt einmal versucht umzusetzen und zwar habe ich im JSON eine Eigenschaft "temp" zugefügt welche ich später weiterverwurschtle um path zu ändern:
Code:
[
        {   "id":"Label-1",
            ...
            "construktor": [
                {
                    ... [COLOR="#FF0000"]// kein path benötigt -> kein temp[/COLOR]
                },
                {
                ...
[COLOR="#FF0000"]                "temp":{ "x": 250, "y": 250, "r": 200},
                "path": "",[/COLOR]
                ...
                },
                {
                    ... [COLOR="#FF0000"]// kein path benötigt -> kein temp[/COLOR]
                }
            ]
           },  {   "id":"Label-2",...}, {   "id":"Label-3",...}, ....

Und das JSON packe ich nach dem Laden in das Objekt: labels. Hier lass ich dann überprüfen ob "temp" vorhanden ist:

Code:
            labels.forEach( function (array) [COLOR="#008000"]// für jedes Element im labels Array[/COLOR]
            {
                array.construktor.forEach( function (array) [COLOR="#008000"]// für jedes Element im construktor Array[/COLOR]
                {
                    if (typeof array.temp != "undefined")
               
                 /* [COLOR="#FF0000"]Fehler -> [/COLOR]
                    array.path = 'M ' + array.temp.x + ' ' + array.temp.y + ' ' +
                    'm ' + -array.temp.r + ',0 ' +
                    'a ' + array.temp.r + ',' + r + ' 0 1,0 ' + (array.temp.r * 2) + ',0 ' +
                    'a ' + array.temp.r + ',' + array.temp.r + ' 0 1,0 ' + (-array.temp.r * 2) + ',0 Z';  
                */
               // array.path = circle(array.temp.x,array.temp.y,array.temp.r); [COLOR="#FF0000"]// Fehler[/COLOR]
                
                  [COLOR="#008000"]console.log("YEAH! array.temp vorhanden"); // wird nur aufgerufen wenn array.temp vorhanden -> passt[/COLOR]

                });
                
            });

Doch hier läuft dann was falsch. Wenn die Berechnungen von array.path via Kommentar "ausschalte" dann wird console.log("YEAH! array.temp vorhanden"); auch nur dann aufgerufen wenn temp auch vorhanden ist -> so soll es sein.

Wenn ich jetzt aber eine der beiden Berechnungen aktiviere ( egal welche ), dann wird es für jedes Element in array.construktor.forEach ausgegeben -> egal ob temp vorhanden oder nicht.

Ein bissi kompliziert zu erklären aber ich hoffe Du weißt was ich meine :icon6:
 
Zuletzt bearbeitet:
Ein bissi kompliziert zu erklären aber ich hoffe Du weißt was ich meine
Ja, ich weiß, was du meinst, und ich weiß auch, woran das liegt: du hast die geschweiften Klammern (also den Block) für das if vergessen. So wie du es geschrieben hast, beeinflusst das if nur die nächste Zeile.

Hier ein Erklärungsbeispiel:
Code:
if (false)
	console.log("wird nicht ausgegeben");
	console.log("wird ausgegeben");

if (false){
	console.log("wird nicht ausgegeben");
	console.log("wird auch nicht ausgegeben");
}
 
Zurück
Oben