Nullppo

メモ帳的なにか

Backboneでscrollイベントが動かねえぇえええ!!!

問題

今、僕はBackboneを使った画面の実装をしてました。
スクロールを使っている画面です。

いつものように

// ・・・・
el : '.sample',
events: {
    'click .button' : 'clickButton',
    'scroll .contents': 'scrollContents'
},
// ・・・・

と書きました。





f:id:nullppo:20170629132542p:plain
おい!動かないじゃねぇか!!!

なんで動かなかったのか

http://backbonejs.org/#View-events
Backbone.View.eventsに書いたイベントは、
jQueryのonを使用して関連付けられます。
rootとなるエレメントはthis.elです。
(英語が苦手だからそんなニュアンスだと思うという予測)

恐らく、上記のeventsはこうなるはず。

$('.sample').on('click', '.button', this.clickButton);
$('.sample').on('scroll', '.scroll', this.scrollContents);

なんか良さそうに見えますよね。
しかーし!!!

scrollイベントは、delegateできないみたいです。

やってみた

See the Pen Scroll Events by Daiki Nakamura (@DaikiNakamura) on CodePen.

はい。動きませんね。

僕は直でONしちゃいました。。。

この問題、renderが終わった後で、
子要素に直接バインドという手段で解決出来ます。(非推奨!

幸いなことにイベントを設定したかったViewは、
rerenderすることのないViewでした。(DOMの書き換えが発生しない)
なので、この手段が使えました。


はい。おわり。

Backbone.jsにおけるMediatorパターン

f:id:nullppo:20170529175721j:plain

業務でBackboneを使っていると、
「View通しの連携をどうしよう。」と悩んだことがありました。

そんな僕が着いた先は、Mediatorパターンによるイベントの連携でした。
調べたこと~サンプル実装までをまとめておこうと思います。

Mediator パターンとは

Mediator とは、英語で「仲裁人、調停者」を意味する単語です。
Mediator パターンとは、多数のオブジェクトの間の調整を行いながら処理をすすめる必要が ある場合に利用すると威力を発揮するパターンです。

ちゃんとしたMediatorパターンでもない気がするけど。。。ま、いっかw

まずは、実装のサンプルから

サンプルでやりたいことは、以下のとおりです。

  1. ViewAで作成したボタンオブジェクトをクリック
  2. ViewBがそれに反応して変わる

(HTMLは省略してます。)

// mediatorの作成
window.App = {};
App.mediator = _.extend({}, Backbone.Events);

// ViewAの定義
var ViewA = Backbone.View.extend({
  events: {
    'click #buttonA': 'clickA' // 1.クリックイベントを取得
  },
  render: function() {
    this.$el.append($('<button></button>', {
      text: 'click me!!',
      id: 'buttonA'
    }));
    return this;
  },
  clickA: function() {
    // 2.イベントが発生したことをmediatorに伝える
    App.mediator.trigger('clickA');
  }
});

// ViewBの定義
var ViewB = Backbone.View.extend({
  initialize: function() {
    // 3.mediatorを購読している、Viewのイベントが発火
    this.listenTo(App.mediator, 'clickA', this.clickA);
  },
  render: function() {
    this.$el.append($('<b></b>', {
      text: 'view B!!',
      id: 'target'
    }));
    return this;
  },
  // 4.実行される関数
  clickA: function(){
    this.$el.find('#target').text('clicked!!')
  }
});


// 描画
var viewA = new ViewA();
var viewB = new ViewB();
$('#MyApp').append(viewA.render().el);
$('#MyApp').append(viewB.render().el);

解説もどき

mediator自体はグローバルな領域に定義されているので、
どのViewからも参照できます。
viewB~FまでlistenToでclickAを購読しておけば、全て反応させる事もできました。
(どんな順番で実行されるかは未確認。)
実際に動きを見たい方は、こちら

また、triggerで引数を渡す場合は、

App.mediator.trigger('clickA', 'クリックされました');

のように、書けばOKです。


とりあえず、以上。
なんかイマイチな記事になった;

2016年度の日報返信名言集(笑)

私の勤めている会社では新人教育の一環として、日報という制度がある。
先輩に報告書を出し、それに対して先輩がコメントしていく簡単な作業です。

毎年、立候補してトレーナーをやっているのですが、
せっかくなので後輩にアドバイスしたことを今年の名言として
ココに晒しとくことにしよう。

来年もトレーナーをやる予定なので、振り返りネタにもなるし、
間違ってるよこれ!ってコメントが貰えるかもしれないしねw

ちょっと恥ずかしいけど、まー(なんやかんや)大丈夫でしょう。

ちなみに、トレーニーがダメだったとかそういうのではないです。
僕のトレーニーは心に突き刺さるエレベーターピッチを日報に書いたり、アドバイスに対して即効で修正してきたりと、素晴らしかったと思います!
ココに書くのを本人が嫌がったらソット削除します!

では早速。

1.目標の中に抽象的な言葉が含まれていたパターン

○○できるようになる。

系の目標ですね。

それに対する私の返信

これって、どうなったら出来た!って言えるんでしょう。
XXさんから「AA君の説明は素晴らしい!」と褒められたらですかね?
分析(←目標に対する分析のこと)のほうにも、「なんとかなった」としか記載がないので、
読み取れなかったです。抽象的な表現はせず、詳細がイメージできるような目標がいいですよ。
イメージしにくいと、目標への意欲も減ってしまう恐れがありますので。
(と、偉そうに言ってますが、僕自身も抽象的な目標を立ててしまう人ですorz)

2.↑に対して、どのように目標設定すればいいかアドバイスを求められたパターン

どうしても抽象的な目標になりがちです。アドバイスください。

系の質問ですね。

それに対する私の返信

お、聞き返してくれる!嬉しいです。
私なりの方法は、「目標を達成した自分がイメージできるか想像してみる」です。
>説明できるようにする。
この目標なんですが、達成した自分を想像してみてください。
その時、AAさんはどんな状態ですか?
その状態を書けば、きっと具体的な目標になっているはずです。
「XXさんに褒められた」でもいいですし、「説明に対する質問に全て回答できた」とか。
状態が思い浮かばないなら、その目標は重要ではないかもしれません。
なぜその目標なのかを自問自答して深堀りしてもいいですし、
目標チェンジしてもいいかもしれません。

ネットで探すと、方法はいくらでもあります。
自分なりの方法に出会えるといいですね。
後は「慣れ」もありますよ。
研修期間中、目標を立てることが多いとおもいます。いい機会ですので、慣れておきましょう!

3.目標がタスクパターン

タスクを終わらせる!

系の目標ですね。

それに対する私の返信

ちょっと内容に突っ込みますmm
スケジュール通りに作業を進められるようになりたい!ということですが、
タスクを終わらせるっていう目標は、上記の「思い」を解決できると思います?
AA君が思うのであれば問題ないのですよ!
僕的にはタスクを終わらせるために、「いつもと違う工夫」を目標に設定して欲しいな!って思いました。
でないと、またタスクが終わらないという問題が発生しそうで。。ループな気がw

4.数を意識しすぎる目標分析パターン

数値目標に対して数値がどうだった!

系の結果分析ですね。(数値に関する分析しかしていない

それに対する私の返信

3つの目標に対して振り返りをしてもらいましたが、
とっても重要なことが抜けているので、アドバイスしますね。
正直に言うと、「達成度合い」だとか「数」だとかは、僕にとって
どーーーでもいいです。。。(まぁ数を出せって言われるからやらなきゃいけないんだけど。

どっちかというと、目標に向かってアクションを起こした結果、
AA君の仕事内容とか夢とか人生、気持ちにどう影響を与えたかが興味あります。
プラスに働いたでしょうか?それとも変わらず?
分析内容ではそういった内容で書いて欲しかったです。
(今度からそんな感じで書いてくれると嬉しいな(*^^*)
数を達成していても、プラスに働いてなければもったいない!

取り組んでみてよかったことや悪かったことを脳内やメモ帳などに
たっくさんあげていきましょう。そして、1個か2個くらいをピックアップし、
もうちょっと深く考えてみましょう。コツは自分に問い掛けてみることです。
「なぜ?」「どうなった?」「どうなる?」みたいな感じで。
それを繰り返すことで、きっといい分析ができると思います。
最初は難しいと思いますが、頑張ってみてください。
実は僕も、つい最近までできませんでした。。。。今もかも。。。

5.目標が目先のことパターン

目先のタスクを片付ける

系の目標ですね。

それに対する私の返信

承知しm。。。。
って思ったけど、アドバイス1つ。
今回の目標は、とっても大切なことだとは思います。
でも、さらに良くする方法があります!
それは、、、目標設定をする際、
特に強い思い?がない限り「目先のタスクに焦点を当てない」ことです。
後、自分を分析してみるのも有効です。AA君の持っているスキルは何でしょう?
ゴール(全タスク完了)に対して、そのスキルをどう活かせばいいでしょう?
そのゴールに向かって行動することで、どう社会に貢献できるでしょう?
このような感じで自問自答を日々繰り返しながら、目標を考えてみましょう!
もっと成長を促せるような目標にたどり着けるはず!?

晒してみて

転記しながら振り返ると、
自分なりには間違ってないかなーって思います。

さて、、、公開しますよーw

Highchartsに好きなパラメータを渡す方法

何がしたいか

Highchartsのツールチップは、勝手にグラフの値を出してくれるので
非常に便利です。僕も愛用していますmm

しばらく使っているうちに、
ツールチップ「グラフの値以外も出したい!」といった欲が出てきました。
そんな時の解決方法を書きたいと思います。

解決方法

--解決前--

棒グラフを出力する際は、以下のようなコードを書くと思います。

<!--通常の棒グラフ-->
<div class="subTitle">
    <h2>通常の棒グラフ</h2>
</div>
<div class="chartArea" id="chart1"></div>

<!--サンプルスクリプト-->
<script type="text/javascript">
$(function () {
    $('#chart1').highcharts({
        chart: {
            type: 'column'
        },
        xAxis: {
            categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
        },
        plotOptions: {
            series: {
                allowPointSelect: true
            }
        },
        series: [{
            data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
        }]
    });
});
</script>

f:id:nullppo:20160614125524p:plain

--解決後--

まず、dataを指定する際に連想配列を使います。
そして、配列に独自のプロパティを定義して、そこにデータを突っ込めばDONE!!
後はツールチップのオプションで呼び出すだけです。(pointFormatの部分)

<!--複数パラメータを渡した棒グラフ-->
<div class="subTitle">
    <h2>複数パラメータを渡した棒グラフ</h2>
</div>
<div class="chartArea" id="chart2"></div>

<!--サンプルスクリプト-->
<script type="text/javascript">
    $(function () {
        $('#chart2').highcharts({
            chart: {
                type: 'column'
            },
            xAxis: {
                categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
            },
            plotOptions: {
                series: {
                    allowPointSelect: true
                }
            },
            tooltip: {
                pointFormat: '{series.name}: <b>{point.y}</b><br/><b>{point.exParam}</b><br/>',
                shared: true
            },
            series: [{
                data: [
                    {
                        y: 29.9,
                        exParam: 'sample1!'
                    }, {
                        y: 71.5,
                        exParam: 'sample2!'
                    }, {
                        y: 106.4,
                        exParam: 'sample3!'
                    }, {
                        y: 129.2,
                        exParam: 'sample4!'
                    }, {
                        y: 144.0,
                        exParam: 'sample5!'
                    }, {
                        y: 176.0,
                        exParam: 'sample6!'
                    }, {
                        y: 135.6,
                        exParam: 'sample7!'
                    }, {
                        y: 148.5,
                        exParam: 'sample8!'
                    }, {
                        y: 216.4,
                        exParam: 'sample9!'
                    }, {
                        y: 194.1,
                        exParam: 'sample10!'
                    }, {
                        y: 95.6,
                        exParam: 'sample11!'
                    }, {
                        y: 54.4,
                        exParam: 'sample12!'
                    }
                ]
            }]
        });
    });
</script>

f:id:nullppo:20160614125645p:plain

動きを見てみる

CodePenで動きを確認してみましょう
Extend parameter in Highcharts

Javaの数値チェックは何でやるか。。。

Javaで数値チェックと言って、
思いつくのは。。。。。

  1. org.apache.commons.lang.math.NumberUtils.isNumber(String str)
  2. org.apache.commons.lang.math.NumberUtils.isDigit(String str)
  3. org.apache.commons.lang.StringUtils.isNumeric(CharSequence cs)

かなー。

じゃあ、
それぞれの違いってなんだろ?
っていう初心者チックな疑問について調べてみた。


1.NumberUtils.isNumber(String str)

  2進数でも16進数でもjavaが解釈できる数値であれば「true
  NumberUtils#isNumberが数値として判定するのは以下の場合
  ・0xで始まる16進数表現
  ・数字のみでの数値表現(小数表現、負符号可)
  ・数値タイプ(long値の場合の末尾のLなど)が指定された数値表現(小数表現、負符号可)
  ・指数表現

2.NumberUtils.isDigit(String str)

  正の整数と0ならば「true
  0が先頭でも「true
  空は「false

3.StringUtils.isNumeric(CharSequence cs)

  正の整数と0ならばtrue
  0が先頭でもtrue
  空は「true


簡易表にしてみた

NumberUtils.isNumber NumberUtils.isDigit StringUtils.isNumeric
NULL("null") false false true
空("") false false true
ゼロ(0) true true true
正の整数(1) true true true
負の整数(-1) true false false
指数(2.5E-4) true false false
【全角】正の整数(1) false true true
【全角】負の整数(-1) false false false

(【TODO】まだ追加で書くかも)

ノンブロッキングI/Oとは何なのか調べてみた

今行ってる現場で、node.jsというキーワードが出てきた。
が、、、、あまりnode.jsを知らない。
(node.jsとExpress、Jade?でウェブアプリ作れたはず、、、くらい。)

なので、node.jsでググった。
すると、ノンブロッキングI/Oというものが出てきて、
さらにそのキーワードを調べたらなかなか面白かったので、記事にしてみよう。

node.js初心者かつノンブロッキング初心者なので、間違った事言ってたらゴメンナサイ。

料理で説明

ググっても、なかなか引用できそうな説明がない。(コピペできんorz
だから、肉じゃがを作ることにする。(いきなりw)
もちろんご飯とお味噌汁付きだ。

まず、炊き上がるまで時間がかかりそうなご飯から。
米を洗い、炊飯器にセットし、ボタンを押す。
あとは通知(ピーピーピー)が来るのを耳を立てて?待つのみだ。

さて、次は肉じゃがを作ろう。
材料を切り、鍋に入れ、調味料を入れ、煮る。
煮終わるまでちょいと時間がかかるので、
お味噌汁とサラダを作ろう。

お味噌汁を作りなーがー。。。
あれ、肉じゃができる?確認してみよう。(爪楊枝をじゃがに刺す)
あれ、硬い。まだか。
よし、お味噌汁完成した。

つぎはサラダ。
ぱぱと切って・・・
あれ、肉じゃができる?確認してみよう。(爪楊枝をじゃがに刺す)
あれ、硬い。まだか。
切った野菜を皿に盛って、完成!

あれ、肉じゃができる?確認してみよう。(爪楊枝をじゃがに刺す)
お!きたー!柔らかい!
肉じゃがを皿に盛って、完成。

炊飯器「ぴーぴーぴー」
よし、ご飯もできたから皿に盛って、完成!

例えはコレだけにしときましょうww

非同期I/O

ご飯は非同期で作りました。
通知をバックグラウンドで待機しておいて、
通知が来たら皿に盛るという処理をしたのです。
通知が来るまでの間、別の処理を実行できますね!

ノンブロッキングI/O

肉じゃがは、ノンブロッキングで作りました。
鍋に入れて煮始めてから、できるまでの間に他の処理をしました。
しかし、たびたび爪楊枝で刺す事で「じゃが」のステータスを確認し、
煮えていた場合、皿に盛るという処理をしたのです。

両者の違い

通知をバックグラウンドで待つのが非同期。
ステータスを決まった間隔で確認しに行くのがノンブロッキング

そもそも

なぜノンブロッキングI/Oというものが出てきたのか。。。

少し前にC10K問題というものがありました。
apacheは、マルチプロセスモデル/マルチスレッドモデルを採用していました。
上記のモデルでは、1クライアントに対して1プロセス/1スレッドが割り当てられます。
10000クライアントが同時にアクセスすることで10000プロセスが立ち上がり、プロセスIDがどうのこうの。。。

そこに、登場したのがイベントループモデルを採用したNginxです。
イベントループモデルはシングルスレッドでループ処理をまわし、キューに溜まったイベントを処理していきます。
C10K問題を解決したわけです。

しかし、イベントループモデルにも弱点がありました。
それは、コードのどこかでブロックする処理が発生すると、、、
イベントループ自体の処理もストップしてしまい、パフォーマンスに大きく影響してしまうことです。

イベントループにおいてブロックする処理をなくそうということで出てきたものが、
「ノンブロッキング」ってわけです。


以上。(間違ってたらゴメンナサイmm

I wish you a happy new year


明けましておめでとうございます。
あなたにとってよい年になりますように。



ということで、
新年1発目の記事です。

iBeaconの記事も下書きのまま年を越してしまいました(汗
そして技術ネタも特にないので、
今年の目標でも。。。

今年の目標

  1. 与えられた仕事を頑張る
  2. 自社のインフラ整備に力を尽くす(だめだったら、、、|彡ッサ
  3. 目指せ1ヶ月3記事以上(本記事もカウントしまwww
  4. 帰省以外でプライベート旅行に行く


こんな感じでいいのかな。

ねよう。