2016-08-08 36 views
0

Ich habe eine Liste von Symbolen auf einer Webseite, die von einem Objekt-Array generiert wurde. Wenn der Benutzer auf ein Symbol klickt, wird das entsprechende Objekt aus dem Array an eine Funktion in einer Fabrik übergeben, die den Namen des ausgewählten Objekts speichert, und dann wird $state.go aufgerufen, um Routen zu ändern. Auf der neuen Route wird ein Controller geladen, der dieselbe Factory lädt und versucht, auf den Namen des gespeicherten Objekts zuzugreifen. Das Problem ist, dass etwa 7 mal von 10, es funktioniert perfekt, und die anderen 3-mal gibt es einen Fehler "Unable to property 'name' von undefined oder Null Referenz" Typ Fehler.Controller lädt den Wert nicht von der Fabrik, nachdem sich der Zustand des ui-Routers geändert hat

Hier ist der Regler den gewählten Wert der Fabrik vorbei:

platformHome.controller('PlatformHome', ['$scope', 'appManager', '$state', function ($scope, appManager, $state) { 

    var SF = appManager.state.SF; 
    var SO = appManager.state.SO; 

    $scope.productLineSelected = function (product) { 
     setProductLine(product);      
    }; 

    function setProductLine(product) { 
     SF.setProduct(product); 
     $state.go('metricDashboard');  
    } 

}]); 

Hier ist die Fabrik:

applicationManager.factory('appStateManager', ['$rootScope', '$sessionStorage', '$state', function ($rootScope, $sessionStorage, $state) { 

// STATE OBJECT CLASSES 
// 
var stateClasses = {}; 

stateClasses.ProductLine = function (name) { 
    this.name = name; 
    this.dashboard = { 
     mode: 'reporting', //reporting, analysis 
     modeView: 'canvas', //canvas, data 
     index: { 
      report: 0, 
      userReport: 0, 
      canvas: 0, 
      group: 0, 
      element: 0, 
      filter: 0, 
     } 
    }; 
    this.reports = []; 
    this.canvases = [new stateClasses.Canvas]; 
}; 


// STATE DATA FUNCTIONS 
// 
var stateFunctions = {}; 

stateFunctions.setProduct = function (product) { 
    session.StateObject.productLine.current = product.Code; 
    session.StateObject[product.Code] = (typeof session.StateObject[product.Code] === 'undefined') ? new stateClasses.ProductLine(product.Name) : session.StateObject[product.Code]; 
}; 


// STUCTURE 
// 
var stateScope = $rootScope.$new(true); 

var session = $sessionStorage; 
session.StateObject = (typeof session.StateObject === 'undefined') ? new stateClasses.StateObject : session.StateObject; 

stateScope.SO = session.StateObject; 
stateScope.SF = stateFunctions; 

return stateScope; 

}]); 

Hier ist der Controller versucht, den Namen zuzugreifen:

metricDashboard.controller('MetricDashboard', ['$scope', 'appManager', function ($scope, appManager) { 

    var SF = appManager.state.SF; 
    var SO = appManager.state.SO; 

    DSO = SO[SO.productLine.current]; 
    $scope.name = DSO.name; 

}]); 

Ich vermute, dass das Problem im Zusammenhang mit der Reihenfolge, in der Dinge passieren, jedoch kann ich nicht f Ich habe herausgefunden, warum es 7 mal von 10 funktioniert.

Wenn ich den Fehler bekomme, konnte ich feststellen, dass die Zeile SO.productLine.current im zweiten Controller einen Wert von none hat, was bedeutet, dass es nicht zu haben scheint aus dem Bereich des Controllers aktualisiert wurde, gleichzeitig verwende ich aber auch console.log(JSON.stringify()) innerhalb der Fabrik, und die Fabrik zeigt tatsächlich einen richtigen Wert anstelle von none.

Ich habe auch versucht mit $timeout auf $state.go, und auch versucht, es als Rückruf, aber keiner von denen verhindert das Problem. Erneut 7 mal von 10, der Code läuft gut und die Name-Eigenschaft ist Wert, aber manchmal ist es nicht.

Antwort

0

Ich konnte das Problem mit ein paar Schritten beheben. Die Idee ist, die Zuweisung der DSO Variable aus dem MetricDashboard Controller zu entfernen und diese Funktionalität der Zuweisung in die Fabrik zu verschieben, dann verweisen Sie einfach die neu zugewiesene Variable zurück in der Steuerung.

Hier sind die Änderungen:

In der Fabrik

... 

// STATE DATA FUNCTIONS 
// 
var stateFunctions = {}; 

stateFunctions.setProduct = function (product) { 
    session.StateObject.productLine.current = product.Code; 
    session.StateObject[product.Code] = (typeof session.StateObject[product.Code] === 'undefined') ? new stateClasses.ProductLine(product.Name) : session.StateObject[product.Code]; 

     //new functionality for assignment 
     session.DynamicStateObject = session.StateObject[product.Code]; 
     stateScope.DSO = session.DynamicStateObject; 
}; 


// STUCTURE 
// 
var stateScope = $rootScope.$new(true); 

var session = $sessionStorage; 
session.StateObject = (typeof session.StateObject === 'undefined') ? new stateClasses.StateObject : session.StateObject; 

    //new structure to persist assignment beyond page refresh 
    session.DynamicStateObject = (typeof session.DynamicStateObject === 'undefined') ? {} : session.DynamicStateObject; 

    //new reference 
    stateScope.DSO = session.DynamicStateObject; 

stateScope.SO = session.StateObject; 
stateScope.SF = stateFunctions; 

return stateScope; 

Kontroller

var SF = appManager.state.SF; 
var SO = appManager.state.SO; 

//Removed assignmnet 
//DSO = SO[SO.productLine.current]; 

//Added reference 
var DSO = appManager.state.DSO; 

$scope.name = DSO.name; 

Während ich noch nicht den neuen Code ausgiebig getestet, habe ich nicht gewesen kann den Fehler reproduzieren.