简体   繁体   中英

Accessing one javascript class inside another

I have two javascript “classes”. One of them is supposed to be a sort of general one, that will instantiate another sub-classes.

Somehow this throws an undefined is not a function error:

    this.progress = new Uploader.Progress({
      matcher: options.matcher,
    });

I'm using underscore as a dependency included through the Rails asset pipeline require statement. Here is the full code:

//= require underscore

if (typeof Uploader === "undefined") {
  var Uploader = {};
}

(function() {
  var Progress = Uploader.Progress = function(options) {
    options || (options = {});

    if(options.matcher) this.$matcher = $(options.matcher);

    this.initialize.apply(this, arguments);
  };

  _.extend(Progress.prototype, {}, {
    initialize: function() {
      this.listen();
    },

    listen: function() {
      this.$matcher.on("fileuploadprogress", function(e, data) {
        var progress = parseInt(data.loaded / data.total * 100, 10);
        data.context.find(".upload-progress").css({ "width": progress + "%" });
      });

      return this;
    },
  });
})();

(function() {
  var Uploader = Project.Uploader = function(options) {
    options || (options = {});

    if(options.url) this.url = options.url;
    if(options.matcher) this.$matcher = $(options.matcher);

    this.progress = new Uploader.Progress({
      matcher: options.matcher,
    });

    this.initialize.apply(this, arguments);
  };

  _.extend(Uploader.prototype, {}, {
    initialize: function() {
      this.listen();
    },

    listen: function() {
      var _this = this;

      this.$matcher.fileupload({
        url: this.url,
        type: "POST",
        dataType: "json",

        add: function(e, data) {
          data.context = _this.$matcher.closest("form");
          data.submit()
            .success(function(result, textStatus, jqXHR) {
              console.log("submitted");
            });
        },
      });

      return this;
    },
  });
})();

var uploader = new Project.Uploader({
  matcher: "#video_file",
  url: "/users/1/videos",
});

u create an uploader object on module scope

if (typeof Uploader === "undefined") {
var Uploader = {};
}

but then u create another local one

var Uploader = Project.Uploader = function(options) ...

binding anything on *this in the local object is not visible in the global one. that is a very strange style.

When you say

this.progress = new Uploader.Progress({
      matcher: options.matcher,
    });

it matched the Uploader defined in the function scope` which is

var Uploader = Project.Uploader = function(options) {

and this one doesn't have a property Progress so Uploader.Progress is undefined . Hence, the error.

To fix that, change

var Uploader = Project.Uploader = function(options) {

To

var SomeOtherVariable = Project.Uploader = function(options) {

so now when you call new Uploader.Progress({ it will start looking for Uploader outside the function scope as it will not find it within the function scope. The correct function set for Uploader.Progress in the global scope would be called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM