1

这可能是我知道的一个非常基本的 Javascript,但我就是不明白..

Ext.regController('Chat', {
    initSocketConnection: function() {
    this.chatStore = new App.Store.Chat();
            ...
    this.socket = io.connect(settings.get('server'), {port: 8080});

    this.socket.on(
        'message',
        this.addMessageToChatStore
    );

},

addMessageToChatStore: function(message) {
    console.log(message);
        console.log(this);     << console shows the 'this' has become SocketNameSpace
    this.chatStore.add(message);   << this line error with "Undefined" chatStore

    this.send(message);
},

控制台打印输出显示函数中"this"addMessageToChatStore"SocketNamespace"

如何摆脱错误?

概括问题。我认为最好将其描述为函数链调用困境。

一个类有一些本地变量,它是另一个类的实例。当这个 var 监听某些事件时,它会调用父类的方法。问题是当这个方法被调用时,它在另一个类的上下文中,因此范围已经改变并且对原始父类方法的访问被拒绝。

4

2 回答 2

0

在 javascript 中,this变量由调用者决定。您可以使用自执行功能来确保您引用正确的实体,而不是使用this

Ext.regController('Chat', (function() {
  var self = {
    initSocketConnection: function() {
      self.chatStore = new App.Store.Chat();
      ...
      self.socket = io.connect(settings.get('server'), {port: 8080});

      self.socket.on(
        'message',
        this.addMessageToChatStore
      );
    },
    addMessageToChatStore: function(message) {
      console.log(message);
      self.chatStore.add(message);
      self.send(message);
    }
  };
  return self;
}()));

更新

基于完整的代码片段,我不确定render函数在哪里定义,如果render是全局函数self.viewChat = render({xtype : 'App.View.Chat'});就足够了,否则它可能被定义在thisthis为调用定义的index)上,所以以下可能就足够了self.viewChat = this.render({xtype : 'App.View.Chat'});

如果我是一个赌徒,我会选择后者,所以代码将是(删除了注释掉的代码):

Ext.regController('Chat', (function() {
    var self = {
        index: function() {
            if (!self.socket) {
                self.initSocketConnection();
            }

            self.showChat();
        },
        /**
         * init the socket connection to the node.js server
         * using user settings
         *
         */
        initSocketConnection: function() {
            self.chatStore = new App.Store.Chat();
            self.chatStore.add({
                user: "Figo",
                message: "Welcome!"
            });
            self.configStore = Ext.StoreMgr.get('ConfigStore');
            var settings = self.configStore.getAt(0);

            self.socket = io.connect(settings.get('server'), {
                port: 8080
            });

            // Event Listener
            self.socket.on('connect', self.registerUser);
            self.socket.on('message', self.addMessageToChatStore);
            App.on('newMsg', self.sendMessageToServer);
        },
        sendMessageToServer: function(msg) {
            self.socket.send(msg);
        },
        addMessageToChatStore: function(message) {
            console.log(message);
            console.log(this);
            console.log(this.parent);

            self.chatStore.add(message);
            self.socket.send(message);
        },
        registerUser: function() {
            self.configStore = Ext.StoreMgr.get('ConfigStore');
            var settings = self.configStore.getAt(0);

            var user = {
                nickname: settings.get('nickname'),
                gravatar: settings.get('gravatar')
            };
            console.log(user);
            self.socket.send(user);
        },
        /**
         * Show chat view
         */
        showChat: function() {
            if (!self.viewChat) {

                self.viewChat = this.render({
                    xtype: 'App.View.Chat'
                });

                self.viewChat.query('#settingsButton')[0].on('tap', self.showConfig, self);
            }
            self.application.viewport.setActiveItem(
            self.viewChat, {
                type: 'slide',
                direction: 'left'
            });
        },
        /**
         * Show config View
         */
        showConfig: function() {
            Ext.dispatch({
                controller: 'Viewport',
                action: 'showConfig'
            });
        }
    };
    return self;
}()));
于 2012-07-03T10:38:45.160 回答
0

对于@Rich.okelly

这是错误(在代码中突出显示)

Uncaught TypeError: Object #<Object> has no method 'render' app.all.js:438
self.showChat app.all.js:438
self.index app.all.js:351
Ext.util.Dispatcher.Ext.extend.dispatch sencha-touch-debug.js:10630
Ext.dispatch sencha-touch-debug.js:10667
Ext.regController.showChat app.all.js:293
fire sencha-touch-debug.js:979
Ext.util.Observable.Ext.extend.fireEvent sencha-touch-debug.js:595

这是完整的代码(同一项目中的其他代码未显示):

Ext.regController('Chat',(function() {
    var self = {
    /**
     * Index action
     *
     * @return {void}
     */
    index: function() {

        if (!self.socket) {
            self.initSocketConnection();
        }

        self.showChat();
    },

    /**
     * init the socket connection to the node.js server
     * using user settings
     *
     */
    initSocketConnection: function() {
        self.chatStore = new App.Store.Chat();
        self.chatStore.add({user: "Figo", message: "Welcome!"});
        self.configStore = Ext.StoreMgr.get('ConfigStore');
        //this.configStore = new App.Store.Config()
        var settings = self.configStore.getAt(0);

        //this.socket = new App.util.Socketio(settings.get('server'), {port: 4000});
        //this.socket.connect();
        self.socket = io.connect(settings.get('server'), {port: 8080});

        /*
        this.socket.on('message', function (data) {
                console.log(data);
                this.parent.addMessageToChatStore(data);
                this.emit('message', data);
        });

        this.socket.on('message', 
                this.addMessageToChatStore
        );
         */     

        // Event Listener

        self.socket.on(
            'connect',
            self.registerUser
        );


        self.socket.on(
            'message',
            self.addMessageToChatStore
        );


        App.on(
            'newMsg',
            self.sendMessageToServer
        ); 
    },

    sendMessageToServer: function(msg){
        self.socket.send(msg);
    },


    addMessageToChatStore: function(message) {
        console.log(message);
                  console.log(this);
                  console.log(this.parent);
        //if (!this.chatStore)
        //this.chatStore = new App.Store.Chat();
        self.chatStore.add(message);
        //App.Controller.Chat.chatStore.add(message);

        self.socket.send(message);
    },


    registerUser: function() {
        self.configStore = Ext.StoreMgr.get('ConfigStore');
        var settings = self.configStore.getAt(0);

        var user = {
            nickname: settings.get('nickname'),
            gravatar: settings.get('gravatar')
        };
        console.log(user);
        self.socket.send(user);
    },

    /**
     * Show chat view
     */
    showChat: function() {
        if (!self.viewChat) {

            self.viewChat = self.render({    << fails over here
                xtype: 'App.View.Chat'
            });

            self.viewChat.query('#settingsButton')[0].on(
                'tap',
                self.showConfig,
                self
            );
        }
        self.application.viewport.setActiveItem(
            self.viewChat,
            {
                type: 'slide',
                direction: 'left'
            }
        );
    },

    /**
     * Show config View
     */
    showConfig: function() {
        Ext.dispatch({
            controller: 'Viewport',
            action    : 'showConfig'
        });
    }

    };
    return self;
}()));
于 2012-07-03T12:39:22.047 回答