在AngularJS模块中包装javascript类并注入angular服务的正确方式



在我正在开发的AngularJS模块中,我有一个Canvas类定义为:

angular.module("myModule", [])
.factory("Canvas", function() {return Canvas;});
var Canvas = function(element, options) {
    this.width = options.width || 300;
    this.height = options.height || 150;
    this.HTMLCanvas = $(element).get(0);
    this.HTMLCanvas.width = canvas.width;
    this.HTMLCanvas.height = canvas.height;
    this.objects = [];
    //Initialize canvas
    this.init();
}
Canvas.prototype.init = function() {/*...*/};
Canvas.prototype.otherMethod = function() {/*...*/};

现在,Canvas类从未从模块内部实例化,而是从AngularJS控制器实例化,如下所示:

angular.module("myApp.controllers", ["myModule"])
.controller("MainCtrl", ["Canvas", function(Canvas) {
    var canvas = new Canvas("#canvas", {/*options object*/});
    //...
}]);

到目前为止,一切都像一种魅力。但后来我意识到我的画布对象中需要$q服务,由于我不想将其注入控制器,然后将其传递给Canvas构造函数,所以我想修改我的模块,如下所示:

angular.module("myModule", [])
.factory("Canvas", ["$q", function(q) {
    var that = this;
    that.q = q;
    return function() {
        Canvas.apply(that, arguments);
    };
}]);
var Canvas = function(element, options) {
    console.log(this.q, element, options);
    this.width = options.width || 300;
    this.height = options.height || 150;
    this.HTMLCanvas = $(element).get(0);
    this.HTMLCanvas.width = canvas.width;
    this.HTMLCanvas.height = canvas.height;
    this.objects = [];
    //Initialize canvas
    this.init();
}
Canvas.prototype.init = function() {/*...*/};
Canvas.prototype.otherMethod = function() {/*...*/};

初始console.log正确地记录了$q服务和Canvas的原始参数elementoptions,但中断了对其init方法的调用:

TypeError: undefined is not a function

我想这是因为this不再是Canvas的实例,而是匿名函数function(q) {...}的实例
关于如何使用q属性实例化新的Canvas对象并仍然保留类的方法,有什么提示吗?

编辑

我稍微修改了我的代码,以便更好地了解我想要实现的目标:

angular.module("myModule", [])
//.factory("Canvas", function() {return Canvas;})
//.factory("Canvas", ["$q", CanvasFactory])
function CanvasFactory(q) {
    var canvas = this;
    canvas.q = q;
    return function() {
        Canvas.apply(canvas, arguments);
    };
}
var Canvas = function(element, options) {
    console.log(this instanceof Canvas, typeof this.q !== "undefined");
};

如果我取消注释第一个工厂,则console.log产生true false,而第二个工厂产生false true。我的目标是获得true true,这意味着this实际上是Canvas的一个实例,并且定义了q属性。任何提示都将不胜感激。

我发现了:

angular.module("myModule", [])
.factory("Canvas", ["$q", function(q) {
    Canvas.prototype.q = q;
    return Canvas;
}]);
var Canvas = function(element, options) {
    console.log(this instanceof Canvas, typeof this.q !== "undefined");
};

此日志记录:true true

我创建了这样的Canvas服务,并且正在工作:

var app = angular.module('myModule', []);
app.factory("Canvas", ["$q", function($q) {
    var Canvas = function(element, options) {
        this.q = $q;
        this.init();
        console.log(this.q, element, options);
    }
    Canvas.prototype.init = function() {/*...*/};
    Canvas.prototype.otherMethod = function() {/*...*/};
    return Canvas;
}]);
app.controller('MainCtrl', ['$scope', 'Canvas', function($scope, Canvas) {
    console.log( new Canvas().q );  
}]);

您也可以在Pluncer上看到这一点,这里是

最新更新