RxJSを使い、配列のデータを1件ずつ待ちを挟みながら処理していく。

前回の記事をRxJSを使って書き直したような感じの内容。 前回との違いは元になるデータが配列ってところくらい。

private messages = [];
private messageArray = [{message: 'テストメッセージ1'}, {message: 'テストメッセージ2'}]
const delayObservable = Rx.Observable.empty().delay(1000); // 1秒待ちを入れるobservableを作っておく
let messageObservable = Rx.Observable.from(this.messageArray)
    .concatMap(msg => {
        return Rx.Observable.empty().concat(delayObservable).concat(Rx.Observable.of(msg)); // 1秒のディレイを挟みつつ、メッセージをsubscribeのコールバックへ流す
    });

const initMessageSubscription = messageObservable.subscribe(
    (msg) => {
        this.messages.push(msg); // メッセージを順次処理する
    },
    (err) => {
        console.error(err);
    },
    () => {
        initMessageSubscription.unsubscribe(); // 終わったらunsubscribeする。
    }
);

cyubachi.hatenablog.com

Promiseを使って非同期の処理を直列に処理する方法。

4~5年くらい前にPromiseがイマイチ理解できずにコールバックのネストで済ませてしまった問題をようやく解決できた。。。

Promise.resolve()
.then(() => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // 何か処理を書く
            resolve();
        }, 1000);
    });
})
.then(() => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // 何か処理を書く
            resolve();
        }, 1000);
    });
});
````

IE9で表示崩れするが、開発者モードを立ち上げると表示崩れがなくなる。

IE9で表示崩れがおきると報告を受けたけど 自分のIE9(開発者モード立ち上げ時)では表示崩れが起きないという事例。

実行されているjavascriptのコードにこんなコードがあり

"use strict"

...

if(console.log) {
  ...
}

IE9ではconsole APIに対応していないらしく、console自体がundefinedだったため
このコードの実行時にエラーが出てしまい、以後の整形を行うスクリプトが実行されずに
表示崩れを起こしているというオチでした。

厄介なところは開発者モードだとconsoleが定義されて
正しく動いてしまうというところ。

  1. IEの開発者ツールからスクリプトデバッガを起動
  2. 開発者ツールを閉じる
  3. IEを閉じる
  4. IEを起動
  5. 該当のページを表示する

という手順を踏んで、スクリプトでエラーが起きたら
エラーダイアログが表示されるような状態にしてページを表示することによって
やっと原因が突き止められた。

参考:

そういえば、はてブロって最近は埋め込みのリンクなんか貼れるようになったんですね。 便利な世の中になったもんだ

jqueryで別ドメインのsolrに問い合わせした結果を得る

$.ajax({
    url: 'http://otherhost:8983/solr/collection1/select/',
    dataType: "jsonp",
    jsonp: 'json.wrf',
    data:{
        'wt':'json',
        'json.wrf': 'jsoncallback',
        'q': '*:*'
    },
    success:function(json){
        // ここでもらったJSONをごにょごにょする
    },
    error:function(){
        alert('error');
    }
});

クラス内のメソッド内でthisを使いたいときの対応

仕事でボタンをクリックしたらとあるクラスのプロパティに
テキストボックスの値を突っ込みたい。というようなことをやりたかったんだけど
いいやり方が思いつかなかったので以下のように対応してた。

var ClassA = function(){
  this.property = "test";
}

ClassA.prototype.setProperty = function(){

  var that = this;

  $('#button').click(function(){
    // this.property = $('#textbox').val();と書いても
    // thisを指しているのがClassAのインスタンスではないので正しく代入できない。
    
    // 実際にはfunctionの頭にthisを変数に代入してその変数を使うようにする。
    that.property = $('#textbox').val();
  });
}

他にうまい方法がないかなーといろいろ情報をあさってみるとオライリー
JavaScript Good Partsの4.3.2に上記のような方法が書かれていた。
やり方自体は間違ってなかったようだ。ただ、その際の変数は「that」とするのが通例らしい。

jqgridの行選択をラジオボタンにした際にラジオボタンが選択されても行が選択されない問題の対応

jqgridの行選択をラジオボタンにした際に
ラジオボタンが選択されたら行を選択するようにする処理

jqgridの初期化時にgridCompleteイベントを設定してやる。

gridComplete: function(){
  var table = $(this);
  $('[class^=radio]',this).click(function(){
    table.setSelection($(this).val());
  });
}

コレに加えてフォーマッターも定義し、
ラジオボタンのclassをradio1,2,3のように、valueをrowidにしてやると
ラジオを選択した際に行が選択されるようになる。