Javascript 如何使用TypeScript静态注入模式注入“$rootScope”?

Javascript 如何使用TypeScript静态注入模式注入“$rootScope”?,javascript,angularjs,angularjs-scope,typescript,Javascript,Angularjs,Angularjs Scope,Typescript,因此,在获得一个大型模型以angular和typescript进行编译后,我最终得到了以下运行时错误: 10angular.js:12314错误:[ng:cpws]无法复制!复制 不支持窗口或范围实例。 我没有改变任何“实现”,我只是重新构造类以使用TypeScript。我的代码中没有任何地方可以使用angular.copy(在整个应用程序的任何类中)。在我的头撞了很多墙之后,我偶然发现了这个问题。构造函数将$rootScope分配给一个局部变量(由于TS,该变量现在位于原型上)。现在,这是一

因此,在获得一个大型模型以angular和typescript进行编译后,我最终得到了以下运行时错误:

10angular.js:12314错误:[ng:cpws]无法复制!复制 不支持窗口或范围实例。

我没有改变任何“实现”,我只是重新构造类以使用TypeScript。我的代码中没有任何地方可以使用angular.copy(在整个应用程序的任何类中)。在我的头撞了很多墙之后,我偶然发现了这个问题。构造函数将$rootScope分配给一个局部变量(由于TS,该变量现在位于原型上)。现在,这是一种旧代码,我只使用了$rootScope的一个ref,将其用作使用
$rootScope.broadcast(…)
的所有视图控制器的通用事件调度器。当我使用标准的棱角样板注射它时,它工作得很好,我可以重构它

/// <reference path="../../app/reference.ts" />
class UserModel {
  roles:string;
  activeRole:string;
  errorString:string;
  loginAttemptEmailValue:string;
  successString:string;

static $inject = ['utils', '$rootScope','$q', '$cookies', '$http','settings', '$location'];
  constructor(u,r,q,c,h,s,l) {
    this.utils = u;
    this.rootScope = r; // <---- the problem. comment-out this line and it works.
    this.q = q;
    this.cookies = c;
    this.http = h;
    this.settings = s;
    this.location = l;
  }
...

angular.module('App').service('userModel', UserModel );

所以,在这里回答我自己的问题,是否还有其他人撞上了同样的砖墙。我认为这种情况可能是一个角度错误或缺少有关将
$rootScope
分配给服务中的局部变量的文档

注入
$scope
$rootScope
并分配给本地引用属性似乎工作正常,在控制器中,而不是在服务中。我还注意到,您根本无法将
$scope
导入到服务中,也许angular团队本想阻止注入
$rootScope
,但却忽略了这一点


错误本身令人费解;我最好的推测是,有一个来自编译的工件(深入Angular的内部),其中服务的实例化尝试深度复制
$rootScope
属性,而不是浅层复制,如果且仅当它被分配给服务对象上的属性时

我也有同样的问题。就是这个东西

at Scope.$digest (angular.js:15666)
您将UserModel作为服务传递给angular,并在每个公共属性上添加angular监视,包括所有这些

this.utils = u;
this.rootScope = r;
this.q = q;
this.cookies = c;
this.http = h;
this.settings = s;
this.location = l;
因此,当$digest启动时,您可以尝试

而copy()则会发生:)的错误

我使用存储类的rootScope的外部变量临时解决了这个问题


稍后将用RxJs Observables替换$rootScope用法作为pub/sub。显然,您正在尝试深入观察类的整个实例。如果此对象的属性之一指向范围实例,则不应执行此操作。如果您仍然想这样做,您可以尝试使用getter函数而不是普通属性:
this.getRootScope=()=>$rootScope
,这可能可行,但听起来仍然不是一个好主意。因为出于性能方面的原因,当您深入观察某个对象时,您希望所观察的对象尽可能小。如果您只想检测某些数据中的更改,那么同时在注入的服务中查找更改是否有意义?显然,您将错误的对象传递给了
$watch


(顺便说一句,我建议使用ngAnnotate而不是手工编写
static$inject…

澄清请求:如果您注释掉
this.rootScope=r那么你的应用程序仍然运行良好(减去广播)?是的!正是这一行让应用程序立即出错。我可以注释掉它,然后在程序执行时得到一个正常的空错误。这很有意义,您是否能够共享使用
$rootScope
的代码。你上面的作业是正确的。对,我只是用它来广播<代码>this.rootScope.$broadcast('changeRole')可能是另一个广播“loggedOut”之类的。我正在尝试将一个控制器转换为TS,看看这到底有多重要。没有手表。这只是将$rootScope注入服务中的一个问题。。。除非有一些我不知道的手表自动绑定。堆栈跟踪清楚地显示某个地方有一个手表,它跟踪整个
userModel
对象。像这样:
$scope.$watch(userModel,…,true)
。我看到一个摘要,但没有手表。您指的是什么?事实上,消费控制器的实现只监视一个属性loginStatus。this.scope.$watch(()=>{返回this.userModel.loginStatus;},(oldStatus,newStatus)=>{if(oldStatus!==newStatus){this.handleLoginStatusChange();}});摘要是手表加工的地方
angular.copy
被深度监视用来存储被监视表达式的值的副本。如果直接从
$digest
调用
copy
,它只能表示这一点。
at Scope.$digest (angular.js:15666)
this.utils = u;
this.rootScope = r;
this.q = q;
this.cookies = c;
this.http = h;
this.settings = s;
this.location = l;
watch.last = watch.eq ? copy(value, null) : value;
if (isWindow(source) || isScope(source)) {
  throw ngMinErr('cpws',
    "Can't copy! Making copies of Window or Scope instances is not supported.");
}
let rootScope: ng.IRootScopeService;

class Settings() {

  static $inject = [
    '$rootScope'
  ];

  constructor($rootScope: ng.IRootScopeService) {

    rootScope = $rootScope;
  }
}