所以,最后在使用angular和typescript编译大型模型之后,我得到了这个运行时错误:
10angular.js:12314错误:[ng:cpws]无法复制!制作副本 不支持窗口或范围实例。 http://errors.angularjs.org/1.4.1/ng/cpws
at angular.js:68
at copy (angular.js:857)
at copy (angular.js:932)
at copy (angular.js:888)
at Scope.$digest (angular.js:15666)
at Scope.$apply (angular.js:15935)
at bootstrapApply (angular.js:1624)
at Object.invoke (angular.js:4443)
at doBootstrap (angular.js:1622)
at bootstrap (angular.js:1642)
我没有改变任何"实施"我只重新构造了类以使用TypeScript。在我的代码中没有使用angular.copy(在整个应用程序的任何类中)。经过多次撞墙后,我偶然发现了问题。构造函数将$ rootScope分配给局部变量(由于TS,现在在原型上)。现在,这是一种旧代码,我只使用ref to $ rootScope将其用作使用$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 );
但这让我担心当我转换我的控制器时,我会遇到同样的问题,只需注入$ scope。
所以,我的问题是,如何使用这种TypeScript静态注入器模式正确注入$scope
而不会遇到这种可怕的复制错误?
我尝试制作一个类级别的静态范围变量,但当然你试图分配给静态类型时会出现左手分配错误。
更新 这是已编译的js。
var UserModel = (function () {
function UserModel(u, r, q, c, h, s, l) {
var _this = this;
this.utils = u;
this.rootScope = r;
this.q = q;
this.cookies = c;
this.http = h;
this.settings = s;
this.location = l;
}
UserModel.prototype.hasActiveRole = function (val) {
if (this.activeRole === val) {
return true;
}
return false;
};
//...other implementation...
UserModel.$inject = ['utils', '$rootScope', '$q', '$cookies', '$http', 'settings', '$location'];
return UserModel;
})();
angular.module('App').service('userModel', UserModel);
答案 0 :(得分:1)
所以,在这里回答我自己的问题,其他人应该碰到同样的砖墙。我认为这种情况可能是Angular错误或缺少有关将$rootScope
分配给服务中的本地变量的文档。
注入$scope
或$rootScope
并分配给本地参考资产似乎工作正常,在控制器中但不是服务。我还注意到你根本不能将$scope
导入到服务中,也许有角度的团队也意味着也会阻止注入$rootScope
但忽略这样做。
错误本身令人费解;我最好的推测是,有一个来自编译的工件(深入Angular的内容),其中服务的实例化尝试深度复制$rootScope
属性而不是浅复制,当且仅当它被分配给属性时才服务对象。
答案 1 :(得分:1)
显然,您正在尝试深入观察班级的整个实例。如果此对象的某个属性指向范围实例,则您不应该这样做。如果你们都希望这样做,你可以尝试使用getter函数而不是普通的属性:this.getRootScope = () => $rootScope
,这可能有效,但听起来并不是一个好主意。因为性能原因,当您深入观察某些内容时,您希望观察对象尽可能小。如果您只想检测某些数据中的更改,是否有必要同时查找注入服务中的更改?显然,您将错误的对象传递给$watch
。
(顺便说一句,我建议使用ngAnnotate而不是手工编写static $inject...
。)
答案 2 :(得分:0)
有同样的问题。就是这件事
at Scope.$digest (angular.js:15666)
您将UserModel传递给angular作为服务,并在每个公共属性上增加了角度,包括所有这些
this.utils = u;
this.rootScope = r;
this.q = q;
this.cookies = c;
this.http = h;
this.settings = s;
this.location = l;
因此,当$ digest开始时,它会尝试save value as last
watch.last = watch.eq ? copy(value, null) : value;
和copy()发生:),错误为because of
if (isWindow(source) || isScope(source)) {
throw ngMinErr('cpws',
"Can't copy! Making copies of Window or Scope instances is not supported.");
}
我暂时使用存储rootScope的外部变量来解决这个问题
let rootScope: ng.IRootScopeService;
class Settings() {
static $inject = [
'$rootScope'
];
constructor($rootScope: ng.IRootScopeService) {
rootScope = $rootScope;
}
}
稍后将使用RxJs Observables将$ rootScope用法替换为pub / sub