2

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

;(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 的值不再有效。

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

4

2 回答 2

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()根本不起作用的突出问题。

于 2013-04-03T18:52:18.490 回答
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() 方法。十分简单。

于 2013-09-12T17:11:09.447 回答