JS Module模式并调用另一个函数

时间:2013-04-03 17:27:56

标签: javascript oop

所以我反复遇到这种情况:我编写了一个模块图案对象,但是无法从另一个(原型)函数中调用一个函数。

;(function($,window,documnet,undefined) {
    var id,
        _defaults = { };

    var MyObject = function(element,options) {
        this.el = element;
        this.opt = $.extend({},_defaults,options);
        this.init();   //  works fine
    };

    MyObject.prototype.init = function() {
        var self = this;
        self.id = localStorage.getItem('myobject_id');
        if( self.id !== null ) {
             $('#myobject_id').val(self.id);
        }
    };


    MyObject.prototype.fetch = function() {
        var self = this;
        var data = { 
                    action: 'program_fetch',
                    program_idx: $('#program_idx').val()
                   };

        // assume session is valid and has a uri in opt.callback
        $.post( session.opt.callback, data ).complete(function(r){
            var prog = JSON.parse(r.responseText).program;
            self.id = prog.id;

            $('#myobject_id').val( self.id );  // this works

            self.display();                    // this does not work
        });

    }; /* fetch */


    MyObject.prototype.display = function() {
        var self = this;

        $('#myobject_id').val( self.id );

    };  /* display */


    $.fn.MyObject = function(options) {
        return this.each(function(){
            if(!$.data(this,'plugin_MyObject')) {
                $.data(this,'plugin_MyObject', new MyObject(options));
            }
        });
    };

    window.myobject = new MyObject();

})(jQuery,window,document);

据我所知,fetch函数应该设置MyObject的窗口附加实例的值,这样当调用display()函数时,它有一个值可以放置进入HTML输入字段,由#myobject_id标识。

实际上似乎发生的是竞争条件,在此期间分配给self.id的值是可行的,但是.complete(..)回调的范围不再是MyObject.id的值。

我应该如何调用这些东西来实现对象中实例数据的持久性?

2 个答案:

答案 0 :(得分:1)

;(function($,window,documnet,undefined) {
var id, 
    _defaults = { };

var MyObject = function(element,options) {
    this.el = element;
    this.opt = $.extend({},_defaults,options);
    this.init();   //  works fine
};

MyObject.prototype.init = function() {

    id = localStorage.getItem('myobject_id');
    if( id !== null ) {
         $('#myobject_id').val(id);
    }
};

    MyObject.prototype.fetch = function() {
    var data = { 
                action: 'program_fetch',
                program_idx: $('#program_idx').val()
               };

    // assume session is valid and has a uri in opt.callback
    $.post( session.opt.callback, data ).complete(function(r){
        var prog = JSON.parse(r.responseText).program;
        id = prog.id;

        $('#myobject_id').val( id );  // this works
        self.display();               // this does not work
    });

}; /* fetch */


MyObject.prototype.display = function() {
    $('#myobject_id').val( id );
};  /* display */


$.fn.MyObject = function(options) {
    return this.each(function(){
        if(!$.data(this,'plugin_MyObject')) {
            $.data(this,'plugin_MyObject', new MyObject(options));
        }
    });
};

})(jQuery,window,document);

在这个版本中我删除了使用var self = this的模式;在每个函数范围内,因为它掩盖了相同名称的对象级变量。 (无法通过this.var设置对象属性?)

仍然存在 self.display()的未解决问题。

答案 1 :(得分:0)

简单的事实是我不知道如何在JS中构造一个类对象。这是一个简单的模型:

;(function($,window) {

    var self;
    var MyClass = function(opt) {
        self = this;
        return self.init(opt);
    }

    MyClass.prototype = {

        init: function(opt) {
            self.opt = $.extend({},opt);
            // other set up stuff
            return self;
        },

        display: function() {

        },

        show: function() {
            self.display();
        }
    }; /* end of prototype */

    $.fn.myclass = function(opt) {
        return new MyClass(opt);
    }

}(jQuery,window));  /* end of clas object */

jQuery().ready(function($) {
    window.myInstance = $().myclass({ /* options here */ });
    $('#some_button').click( window.myInstance.show );
}

在激活按钮#some_button时,将调用show方法。它反过来将调用display()方法。容易腻。