0

Web ベースのサービス用のクライアント側ライブラリを開発していますが、オブジェクト変数を設定して後で取得する際に問題が発生しています。

図書館の始まりです

var QuickBase = function(username, password, apptoken, realm) {

    this.username = username;
    this.password = password;
    this.apptoken = (typeof apptoken === "undefined") ? '' : apptoken;
    this.realm = (typeof realm === "undefined") ? 'www' : realm;
    this.ticket = '';
    this.dbid = '';
    this.payload = '<qdbapi>';

    this.init = function() {
        var self = this;

        this.authenticate(this.username, this.password, null, null, function(data) {
            var errcode = $(data).find('errcode').text();
            if(errcode > 0)
                throw new Error($(data).find('errtext').text());

            self.ticket = $(data).find('ticket').text();
        });
    }

    this.setBaseUrl = function() {
        var endpoint = this.dbid == '' ? 'main' : this.dbid;
        this.baseUrl = 'https://' + this.realm + '.quickbase.com/db/' + endpoint;
    }

    this.transmit = function(method, callback) {
        this.setBaseUrl();

        if(this.apptoken)
            this.payload += '<apptoken>' + this.apptoken + '</apptoken>';

        if(this.ticket)
            this.payload += '<ticket>' + this.ticket + '</ticket>';

        this.payload += '</qdbapi>';

        console.log(this.payload);

        $.ajax({
            url: this.baseUrl,
            type: 'POST',
            data: this.payload,
            dataType: 'xml',
            headers: {
                'Content-Type': 'application/xml',
                'QUICKBASE-ACTION': method
            },
            success: callback
        });

        this.payload = '<qdbapi>';
    }

    this.addSettingsToPayload = function(settings) {
        for(var key in settings) {
            this.payload += '<' + key + '>' + settings[key] + '</' + key + '>';
        }
    }

    this.authenticate = function(username, password, hours, udata, callback) {
        this.payload += '<username>' + username + '</username>';
        this.payload += '<password>' + password + '</password>';

        this.payload += (typeof hours === "undefined") ? '' : '<hours>' + hours + '</hours>';
        this.payload += (typeof udata === "undefined") ? '' : '<udata>' + udata + '</udata>';

        this.transmit('API_Authenticate', callback);
    }

ユースケースは次のとおりです。

var username = 'foo', password = 'bar', token = 'footoken', realm = 'foorealm';

window.qb = new QuickBase(username, password, token, realm);
$.when(qb.init()).then(function(){ 
  console.log(qb); // shows the object with ticket set
  console.log(qb.ticket); // empty
  qb.doQuery(); // breaks because internal this.ticket is empty
});

私の質問は、qb.ticket が設定されておらず、将来の関数呼び出しで使用できないのはなぜですか?

さらに、.when で .init() をラップする必要がない方法はありますか?

基本的に、init は今後のすべての API メソッドが必要とするチケットを設定します。qb.init() を呼び出してから qb.doQuery() を呼び出すだけでは、init() が終了するという保証はありませんが、.when を使用すると、将来のすべてのメソッド呼び出しが内部にある必要があるということにはなりません。 .then コールバック? それは醜いようです。

4

2 に答える 2

0

init()最も簡単な方法は、次のようにから promise を返すことです。

this.init = function() {
    var self = this;
    var dfrd = $.Deferred();
    this.authenticate(this.username, this.password, null, null, function(data) {
        var errcode = $(data).find('errcode').text();
        if(errcode > 0)
            throw new Error($(data).find('errtext').text());
        self.ticket = $(data).find('ticket').text();
        dfrd.resolve();
    });
    return dfrd.promise();
}

それで :

window.qb = new QuickBase(username, password, token, realm);
qb.init().then(function() {
  console.log(qb);
  console.log(qb.ticket);
  qb.doQuery();
});
于 2013-04-26T00:36:23.273 に答える
0

$.whenpromise オブジェクトを期待します。取得できない場合は、すぐにコールバックを実行します。呼び出しから promiseを返すか、独自の promise を作成する必要があります。$.ajax

しかし、あなたは1つの約束だけで作業しているので、いつでも必要ありません. あなたがすることができます:

qb.init().done(qb.doQuery.bind(qb));

例:

var QuickBase = function(username, password, apptoken, realm) {
    // ...

    this.init = function() {
        var self = this;

        return this.authenticate(this.username, this.password, null, null).done(function(data) {
            var errcode = $(data).find('errcode').text();
            if(errcode > 0)
                throw new Error($(data).find('errtext').text());

            self.ticket = $(data).find('ticket').text();
        });
    }

    this.transmit = function(method) {
        // ...

        var promise = $.ajax({
            url: this.baseUrl,
            type: 'POST',
            data: this.payload,
            dataType: 'xml',
            headers: {
                'Content-Type': 'application/xml',
                'QUICKBASE-ACTION': method
            }
        });

        this.payload = '<qdbapi>';
        return promise;
    }

    this.authenticate = function(username, password, hours, udata) {
        // ..
        return this.transmit('API_Authenticate');
    }
}

.init別の方法として、コールバックを受け入れるようにすることもできます。

this.init = function(callback) {
    var self = this;

    this.authenticate(this.username, this.password, null, null, function(data) {
        var errcode = $(data).find('errcode').text();
        if(errcode > 0)
            throw new Error($(data).find('errtext').text());

        self.ticket = $(data).find('ticket').text();
        callback();
    });
};

その後:

qb.init(function(){ 
  qb.doQuery();
});
于 2013-04-26T00:18:48.507 に答える