我在从对象数组生成的网页上有一个图标列表。当用户单击某个图标时,数组中的相应对象将传递给工厂中的一个函数,该函数会保存所选对象的名称,然后调用$state.go
来更改路径。在新路由上加载控制器,该控制器加载同一工厂并尝试访问已保存对象的名称。问题是,大约7次中有10次,它完美地运行,而其他3次则给出了一个“无法获得属性”的名称'未定义或空引用"类型错误。
这是控制器将所选值传递给工厂:
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');
}
}]);
这是工厂:
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;
}]);
以下是试图访问该名称的控制器:
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;
}]);
我怀疑这个问题与事情发生的顺序有关,但是,我无法弄清楚为什么它在10次中有效7次。
当我收到错误时,我能够确定第二个控制器中的行SO.productLine.current
的值为none
,这意味着它似乎没有更新然而,从控制器的范围来看,我同时在工厂内使用console.log(JSON.stringify())
,工厂确实显示了正确的值而不是none
。
我还尝试在$timeout
上使用$state.go
,并尝试将其作为回调传递,但这些都不会阻止此问题。 10次中有7次,代码运行良好,name属性值,但有时不是。
答案 0 :(得分:0)
我能够通过几个步骤纠正问题。我们的想法是从DSO
控制器中删除MetricDashboard
变量的赋值,并将赋值功能移到工厂中,然后简单地在控制器中引用新分配的变量。
以下是更改:
在工厂
...
// 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;
在控制器中
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;
虽然我还没有广泛测试新代码,但我还是无法重现错误。