在我的角度厂code范围的问题 [英] Scope issues in my Angular factory code

查看:112
本文介绍了在我的角度厂code范围的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个角的工厂名为'DashboardState ,我目前修改通过我的 dashboardcontext 角服务层。

目前我所有的小部件数据都保留在的localStorage 对象;不过,我现在挂接到这台新的C#API层/获取布局小部件/从永久存储(即SQL Server数据库在这种情况下)。

我的主要问题是,当返回this._getItemFromAPI($ rootScope)。然后负载:函数

载:部分,这个与堆栈上的方法有效的对象;但是,。然后部分中我突然无法访问这一点。

这是一个问题,对我来说,因为我再也不能叫 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

\r
\r

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

\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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆