在我的角度厂code范围的问题 [英] Scope issues in my Angular factory code
问题描述
我有一个角的工厂名为'DashboardState
,我目前修改通过我的 dashboardcontext $ C $处理API调用C>角服务层。
目前我所有的小部件
数据都保留在的localStorage
对象;不过,我现在挂接到这台新的C#API层/获取布局小部件/从永久存储(即SQL Server数据库在这种情况下)。
我的主要问题是,当诺
在返回this._getItemFromAPI($ rootScope)。然后$ C $返回c会发生什么>在
负载:
函数
在载:
部分,这个
与堆栈上的方法有效的对象;但是,。然后
部分中我突然无法访问这一点。
。
这是一个问题,对我来说,因为我再也不能叫 this._handleSyncLoad
。正如你所看到的,我已经通过分配尝试了黑客 VAR handleSync = this._handleSyncLoad;
,但它并没有解决问题的范围。
如果(dashboardId = NULL&放大器;!&安培;!dashboardId =未定义){ this.storage.setItem(defaultDashboardId,dashboardId); VAR handleSync = this._handleSyncLoad;
返回this._getItemFromAPI($ rootScope)。然后(功能(数据){
//保存下一次电流的电流仪表盘ID - 2015年6月11日BM: 返回handleSync(数据,真实); });
}
下面是的完整列表'DashboardState
:
angular.module('ui.dashboard')\r
.factory('DashboardState',['$日志,$ Q','dashboardcontext','$ rootScope',函数($日志,$ Q,dashboardcontext,$ rootScope){\r
功能DashboardState(存储,ID,哈希,widgetDefinitions,字符串化){\r
this.storage =存储;\r
this.id = ID;\r
this.hash =散列;\r
this.widgetDefinitions = widgetDefinitions;\r
this.stringify =字符串化;\r
}\r
\r
DashboardState.prototype = {\r
/ **\r
*为小部件实例对象的数组,序列化,并保存状态。\r
*\r
* @参数{}阵部件从仪表盘指令scope.widgets\r
* @返回{}布尔真正的成功,失败假\r
* /\r
保存:功能(部件){\r
// code省略了保存功能\r
返回true;\r
},\r
载:函数(dashboardId){//从导航控制器发送通话中\r
\r
VAR useLocalStorage = FALSE; //从localStorage的或通过API层检索\r
\r
VAR系列化;\r
\r
如果(useLocalStorage){//从localStorage的仪表盘布局\r
// COME code不再赘述\r
系列化= this.storage.getItem(dashboardId);\r
}\r
}\r
其他{\r
\r
//取得仪表板在这里!\r
如果(dashboardId = NULL&放大器;!&安培;!dashboardId =未定义){\r
\r
// ***本可在范围在这一点上***\r
this.storage.setItem(defaultDashboardId,dashboardId);\r
\r
VAR handleSync = this._handleSyncLoad;\r
返回this._getItemFromAPI($ rootScope)。然后(功能(数据){\r
// ***本是的范围不再可用 - 即我不能再从这里调用this._handleSyncLoad ***\r
返回handleSync(数据,真实);\r
\r
});\r
}\r
其他{\r
//恢复原线;看到dashboardOptions主控制器\r
系列化= this.storage.getItem(this.id);\r
}\r
}\r
\r
如果(连载){\r
//检查承诺\r
如果(angular.isObject(序列)){//&放大器;&放大器; angular.isFunction(serialized.then)){//体改线2015年9月4日BM:\r
返回this._handleAsyncLoad(连载)\r
}\r
//否则处理同步负载\r
返回this._handleSyncLoad(连载)\r
}其他{\r
返回null;\r
}\r
\r
},\r
\r
_getItemFromAPI:函数($ rootscope){\r
//服务器端API调用持久化仪表盘储存 - 2015年9月3日BM:\r
VAR SID = $ rootScope.rageSessionVars.sessionID;\r
VAR的userid = $ rootScope.rageSessionVars.userID;\r
VAR dashboardId = this.id;\r
\r
返回dashboardcontext.getDashboardImage(SID,用户ID,dashboardId)。然后(功能(数据){\r
如果(data.status ==FAIL){\r
window.alert(无法检索仪表板。+ data.messages);\r
返回false;\r
}\r
其他{\r
返回的数据;\r
}\r
});\r
},\r
\r
_handleSyncLoad:功能(连载,isParsed){\r
\r
\r
// ****必须处理isParsed PARAM;序列化对象alredy解析****\r
\r
无功序列化,结果= [];\r
\r
如果(!连载){\r
返回null;\r
}\r
\r
如果(这种==未定义){//从this._getItemFromAPI的。那么未来负载的问题,如果: - 2015年9月4日BM:\r
\r
反序列化= JSON.parse(连载)\r
\r
}\r
其他{\r
如果(this.stringify){\r
尝试{//反序列化字符串\r
\r
反序列化= JSON.parse(连载)\r
\r
}赶上(E){\r
\r
//错误的JSON,记录警告和返回\r
$ log.warn('序列化仪表盘状态是畸形的,不能解析:连载);\r
返回null;\r
\r
}\r
}\r
其他{\r
反序列化的序列化=;\r
}\r
}\r
\r
//核对当前哈希散列\r
如果(deserialized.hash!== this.hash){\r
\r
$ log.info('从存储序列化的仪表板是陈旧的(旧的Hash:'+ deserialized.hash +',新的哈希:'+ this.hash +')');\r
this.storage.removeItem(this.id);\r
返回null;\r
\r
}\r
\r
//缓存部件\r
VAR savedWidgetDefs = deserialized.widgets;\r
\r
//从实例存储的数据控件\r
对于(VAR I = 0; I< savedWidgetDefs.length;我++){\r
\r
//反序列化对象\r
VAR savedWidgetDef = savedWidgetDefs [I]\r
\r
//部件定义使用\r
VAR widgetDefinition = this.widgetDefinitions.getByName(savedWidgetDef.name);\r
\r
//检查是否有部件\r
如果(!widgetDefinition){\r
//没有发现小部件的定义,删除和返回false\r
$ log.warn(工具名称为'+ savedWidgetDef.name +'中给出窗口小部件定义的对象没有被发现');\r
继续;\r
}\r
\r
//检查特定部件storageHash\r
如果(widgetDefinition.hasOwnProperty('storageHash')及与放大器;!widgetDefinition.storageHash == savedWidgetDef.storageHash){\r
//定义窗口小部件被发现,但storageHash是陈旧的,删除存储\r
$ log.info('与名称部件定义对象'+ savedWidgetDef.name +'发现'+\r
但小部件定义的storageHash属性不同于上的+\r
序列化小部件的存储加载。从存储哈希:'+ savedWidgetDef.storageHash +''+\r
从WDO散列:'+ widgetDefinition.storageHash +'');\r
继续;\r
}\r
\r
//实例化推部件导致数组\r
result.push(savedWidgetDef);\r
}\r
\r
返回结果;\r
},\r
\r
_handleAsyncLoad:功能(承诺){\r
VAR自我=这一点;\r
变种推迟= $ q.defer();\r
promise.then(\r
//成功\r
功能(RES){\r
VAR的结果= self._handleSyncLoad(RES);\r
如果(结果){\r
deferred.resolve(结果);\r
}其他{\r
deferred.reject(结果);\r
}\r
},\r
//失败\r
功能(RES){\r
deferred.reject(RES);\r
}\r
);\r
\r
返回deferred.promise;\r
}\r
\r
};\r
\r
返回DashboardState;\r
}]);
\r
您的建议是大大AP preciated。
问候,
鲍勃
这个
总是指当前的函数,所以如果你有窝函数定义来解决它以某种方式
这是一个应该解决您的问题一个典型的模式:
函数someFunction(){
VAR认为这=;
DoSomething的()。然后(函数(){
//'那个'你'这个'
});
}
I have an Angular factory called 'DashboardState'
, which I am currently modifying to handle an API call via my dashboardcontext
Angular service layer.
Currently all my widget
data is persisted to the localStorage
object; however, I am now hooking into a new c# API layer which sets/gets the layout widgets to/from permanent storage (i.e. Sql Server database in this case).
My primary issue is what happens when the promise
is returned at return this._getItemFromAPI($rootScope).then
of the load:
function.
In the load:
section, this
is a valid object with methods on the stack; however, within the .then
section I suddenly lose access to this.
.
It's a problem for me because I can no longer call this._handleSyncLoad
. And as you can see, I've tried a hack by assigning var handleSync = this._handleSyncLoad;
, however it doesn't solve the scope issue.:
if (dashboardId != null && dashboardId != undefined) {
this.storage.setItem("defaultDashboardId", dashboardId);
var handleSync = this._handleSyncLoad;
return this._getItemFromAPI($rootScope).then(function (data) {
// save current current dashboard id for next time - 06/11/2015 BM:
return handleSync(data, true);
});
}
Here's the full listing of 'DashboardState'
:
angular.module('ui.dashboard')
.factory('DashboardState', ['$log', '$q', 'dashboardcontext', '$rootScope', function ($log, $q, dashboardcontext, $rootScope) {
function DashboardState(storage, id, hash, widgetDefinitions, stringify) {
this.storage = storage;
this.id = id;
this.hash = hash;
this.widgetDefinitions = widgetDefinitions;
this.stringify = stringify;
}
DashboardState.prototype = {
/**
* Takes array of widget instance objects, serializes, and saves state.
*
* @param {Array} widgets scope.widgets from dashboard directive
* @return {Boolean} true on success, false on failure
*/
save: function (widgets) {
// CODE OMITTED FOR SAVE FUNCTION
return true;
},
load: function (dashboardId) { // sent in from navigation-controller call
var useLocalStorage = false; // retrieve from localStorage or via API layer
var serialized;
if (useLocalStorage) { // retrieve dashboard layout from localStorage
// COME CODE OMITTED FOR BREVITY
serialized = this.storage.getItem(dashboardId);
}
}
else {
// FETCH DASHBOARD HERE !!
if (dashboardId != null && dashboardId != undefined) {
// *** "this" is available on the scope at this point ***
this.storage.setItem("defaultDashboardId", dashboardId);
var handleSync = this._handleSyncLoad;
return this._getItemFromAPI($rootScope).then(function (data) {
// *** "this" IS NO LONGER AVAILABLE ON THE SCOPE - i.e. I can no longer call this._handleSyncLoad from here ***
return handleSync(data, true);
});
}
else {
// revert to original line; see dashboardOptions to main-controller
serialized = this.storage.getItem(this.id);
}
}
if (serialized) {
// check for promise
if (angular.isObject(serialized)) { // && angular.isFunction(serialized.then)) { // modifed line 09/04/2015 BM:
return this._handleAsyncLoad(serialized);
}
// otherwise handle synchronous load
return this._handleSyncLoad(serialized);
} else {
return null;
}
},
_getItemFromAPI: function ($rootscope) {
// SERVER-SIDE API CALL TO PERSIST DASHBOARD TO STORAGE - 09/03/2015 BM:
var sid = $rootScope.rageSessionVars.sessionID;
var userid = $rootScope.rageSessionVars.userID;
var dashboardId = this.id;
return dashboardcontext.getDashboardImage(sid, userid, dashboardId).then(function (data) {
if (data.status == "FAIL") {
window.alert("Failed to retrieve dashboard. " + data.messages);
return false;
}
else {
return data;
}
});
},
_handleSyncLoad: function (serialized, isParsed) {
// **** MUST HANDLE THE isParsed PARAM; serialized object is alredy parsed ****
var deserialized, result = [];
if (!serialized) {
return null;
}
if (this == undefined) { // problem if coming from .then of this._getItemFromAPI in load: - 09/04/2015 BM:
deserialized = JSON.parse(serialized);
}
else {
if (this.stringify) {
try { // to deserialize the string
deserialized = JSON.parse(serialized);
} catch (e) {
// bad JSON, log a warning and return
$log.warn('Serialized dashboard state was malformed and could not be parsed: ', serialized);
return null;
}
}
else {
deserialized = serialized;
}
}
// check hash against current hash
if (deserialized.hash !== this.hash) {
$log.info('Serialized dashboard from storage was stale (old hash: ' + deserialized.hash + ', new hash: ' + this.hash + ')');
this.storage.removeItem(this.id);
return null;
}
// Cache widgets
var savedWidgetDefs = deserialized.widgets;
// instantiate widgets from stored data
for (var i = 0; i < savedWidgetDefs.length; i++) {
// deserialized object
var savedWidgetDef = savedWidgetDefs[i];
// widget definition to use
var widgetDefinition = this.widgetDefinitions.getByName(savedWidgetDef.name);
// check for no widget
if (!widgetDefinition) {
// no widget definition found, remove and return false
$log.warn('Widget with name "' + savedWidgetDef.name + '" was not found in given widget definition objects');
continue;
}
// check widget-specific storageHash
if (widgetDefinition.hasOwnProperty('storageHash') && widgetDefinition.storageHash !== savedWidgetDef.storageHash) {
// widget definition was found, but storageHash was stale, removing storage
$log.info('Widget Definition Object with name "' + savedWidgetDef.name + '" was found ' +
'but the storageHash property on the widget definition is different from that on the ' +
'serialized widget loaded from storage. hash from storage: "' + savedWidgetDef.storageHash + '"' +
', hash from WDO: "' + widgetDefinition.storageHash + '"');
continue;
}
// push instantiated widget to result array
result.push(savedWidgetDef);
}
return result;
},
_handleAsyncLoad: function (promise) {
var self = this;
var deferred = $q.defer();
promise.then(
// success
function (res) {
var result = self._handleSyncLoad(res);
if (result) {
deferred.resolve(result);
} else {
deferred.reject(result);
}
},
// failure
function (res) {
deferred.reject(res);
}
);
return deferred.promise;
}
};
return DashboardState;
}]);
Your advice is greatly appreciated.
regards, Bob
this
always refers to the current function so if you nest function definitions you have to work around it somehow.
This is a typical pattern that should solve your issue:
function someFunction() {
var that = this;
doSomething().then(function() {
// 'that' is your 'this'
});
}
这篇关于在我的角度厂code范围的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!