在AngularJS模块中包装javascript类并注入角度服务的正确方法

时间:2014-08-30 15:39:28

标签: javascript angularjs angularjs-module

在我开发的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*/});
    //...
}]);

到目前为止,一切都像魅力一样。 但后来我意识到我需要在canvas对象中使用$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) {...}
有关如何使用Canvas属性实例化新q个对象并仍然保留类的方法的任何提示?

修改

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

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属性。任何提示都非常感谢。

2 个答案:

答案 0 :(得分:5)

我明白了:

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

答案 1 :(得分:1)

我像这样创建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 here

上看到这个