包装在AngularJS模块JavaScript类和注入角度服务的正确方法装在、模块、角度、正确

2023-09-13 02:47:32 作者:天涯浪人

在我开发一个AngularJS模块,我定义为画布类:

  angular.module(MyModule的,[]).factory(画布功能(){返回帆布;});VAR帆布=功能(元素,期权){    this.width = options.width || 300;    this.height = options.height || 150;    this.HTMLCanvas = $(元件)获得(0);    this.HTMLCanvas.width = canvas.width;    this.HTMLCanvas.height = canvas.height;    this.objects = [];    //初始化帆布    this.init();}Canvas.prototype.init =功能(){/*...*/};Canvas.prototype.otherMethod =功能(){/*...*/}; 

现在,在画布类是永远不会从模块中实例化,而是从AngularJS的控制器,就像这样:

  angular.module(myApp.controllers,[MyModule的]).controller(MainCtrl,[画布功能(画布){    VAR帆布=新的Canvas(#画布,{/ *选项对象* /});    // ...}]); 
结合源码分析 Node.js 模块加载与运行原理

到目前为止一切工作就像一个魅力。但后来我意识到,我需要在我的画布对象中的 $ Q 服务,因为我不希望诉诸注入到我的控制器,然后把它传递给画布的构造,我想修改我的模块,像这样的:

  angular.module(MyModule的,[]).factory(画布,[$ Q功能(Q){    VAR认为这=;    that.q = Q;    返回功能(){        Canvas.apply(即,参数);    };}]);VAR帆布=功能(元素,期权){    的console.log(this.q,元素,期权);    this.width = options.width || 300;    this.height = options.height || 150;    this.HTMLCanvas = $(元件)获得(0);    this.HTMLCanvas.width = canvas.width;    this.HTMLCanvas.height = canvas.height;    this.objects = [];    //初始化帆布    this.init();}Canvas.prototype.init =功能(){/*...*/};Canvas.prototype.otherMethod =功能(){/*...*/}; 

最初的的console.log 正确记录了 $ Q 服务和帆布的原始参数,元素选项,但休息在调用它的的init 方法:

类型错误:未定义不是一个函数

我想这是因为这个不再画布而是匿名函数的一个实例函数(q){...} 。结果画布属性的对象,并仍然保留类的方法?

修改

我修改我的code稍微给的想什么,我实现一个更好的主意:

  angular.module(MyModule的,[])//.factory(\"Canvas功能(){返回帆布;})//.factory(\"Canvas,[$ Q,CanvasFactory])功能CanvasFactory(Q){    VAR帆布=这一点;    canvas.q = Q;    返回功能(){        Canvas.apply(帆布,参数);    };}VAR帆布=功能(元素,期权){    的console.log(!这的instanceof帆布的typeof this.q ==未定义);}; 

如果我取消了第一家工厂,的console.log 收益率真的假的,而第二工厂的产量假真。我的目标是要获得真真正,这意味着这个其实是在画布类的和的定义了属性。任何暗示大大AP preciated。

解决方案

我想通了:

  angular.module(MyModule的,[]).factory(画布,[$ Q功能(Q){    Canvas.prototype.q = Q;    返回帆布;}]);VAR帆布=功能(元素,期权){    的console.log(!这的instanceof帆布的typeof this.q ==未定义);}; 

此日志:真真正

Inside an AngularJS module I'm developing, I have a Canvas class defined as:

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() {/*...*/};

Now, the Canvas class is never instantiated from inside the module, but rather from an AngularJS controller, like so:

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

And so far everything works like a charm. But then I realized that I need the $q service in my canvas object, and since I don't want to resort to injecting it into my controller and then passing it to the Canvas constructor, I thought of modifying my module like so:

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() {/*...*/};

The initial console.log correctly logs the $q service and the Canvas's original arguments, element and options, but breaks on the call to its init method:

TypeError: undefined is not a function

I suppose that's because this is no longer an instance of Canvas but rather of the anonymous function function(q) {...}. Any hints on how I can instantiate new Canvas objects with the q property and still retain the class's methods?

EDIT

I've modified my code slightly to give a better idea of what I'd like to achieve:

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");
};

If I uncomment the first factory, console.log yields true false, whereas the second factory yields false true. My goal is to get true true, which means that this is in fact an instance of the Canvas class and has the q property defined. Any hint is greatly appreciated.

解决方案

I figured it out:

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");
};

This logs: true true.

 
精彩推荐