Correct way of wrapping javascript class in AngularJS module and inject angular services

穿精又带淫゛_ 提交于 2019-12-30 05:12:15

问题


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.


回答1:


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.




回答2:


I create Canvas service like this and is work:

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

Also you can see this on Pluncer here



来源:https://stackoverflow.com/questions/25584060/correct-way-of-wrapping-javascript-class-in-angularjs-module-and-inject-angular

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!