2013年6月26日水曜日

AngularJSでController間の通信を行う

AngularJSでController間の通信を行うには2つの方法がある。

1つは$rootScopeに値を設定してしまう方法。
もう一つは$broadcast,$onを使う方法。

$rootScopeはグローバルなオブジェクトであるので、アプリ内のどこからでも参照できる。ここに値を設定すると、各Controllerで値を参照することができる。
しかし、これはグローバル変数を使ったプログラムの弊害で、メンテナンス性が悪くなるのでお勧めはできない。簡単に使えるのでつい使用してしまうが、後で困るのは自分なので使わなようにしたい。

そこでAngularJSでは$broadcast,$onメソッドが用意されている。これを使ってpub-subパターンが実現できる。

angular.module('myApp.controllers', []).
 controller('mainCtrl', ['$rootScope', '$scope', function($rootScope, $scope) {

  var date = {"id": 1, "text": "メッセージです"}
  $rootScope.$broadcast('messageBroadcast',data);

 }]).
 controller('subCtrl', ['$scope', function($scope) {

  $scope.$on('messageBroadcast', function(event,data) {

   $scope.message = data;

  });


 }]);

mainCtrlからイベントを発生させ、subCtrlでイベントを受け取とる。
簡単で有効なパターンなのでぜひマスターしておけばいいと思う。

2013年6月24日月曜日

OpenLayerのMarkerイベントでAngularjsを使用する

Mapアプリ向けのjavascriptライブラリOpenLayersを使ってMapアプリを作っている。javascriptフレームワークはAngularjsを使用している。

この2つのライブラリ、フレームワークを使っているが、Dialog表示でハマってしまった。
マップにピンのようなマーカーを表示させ、マーカーがクリックされたら、Dialogを表示させたかった。

この場合は以下のようなコードになる。

イベントの設定
    var marker = new OpenLayers.Marker(lonLat, icon);
    marker.events.register('mousedown', marker, $scope.showDialog);

イベント
    $scope.showDialog = function(evt) {
        $scope.openDialog();
        $rootScope.$apply();  //これ大切!!!
        OpenLayers.Event.stop(evt);
    };

ここで大切なのは$rootScope.$apply();を呼ぶ事だ。 これによりAngularjsのdigestサイクルに制御が移り、非同期動作のDialog処理が実行される。

2013年6月21日金曜日

Angularjsでフォーカスを設定する。Directivesを使ってみた。

AngularJSで入力項目にフォーカスを設定したい。
JQueryではこんな感じになると思う。

$(document).ready( function() {
   $("#inputText").focus()
});

至ってシンプルだ。しかし、AngularJSでは基本的にDOM操作はしない。Controllerにこのコードを書く事はできるが、スマートは方法とはされていない。このような場合、Directivesを作成するのが正しいやり方だ。

AngularJSの説明を読んでみたが、要はDirectivesとはhtmlを拡張するのだ。と書いてあるがよく分からなかった。いつものようにコードを書いてみると意味が理解できた。

<input type="text" id="inputText" nc-init-focus>


nc-init-focusなんて属性は通常では存在していないが、Directivesを書くことでhtmlを拡張し、動きを定義できる。View部分の操作をControllerに持ち込まなくていいし、モジュール化されているので、再利用しやすい。

フォーカスを設定するDirectivesは以下の通り


angular.module('myApp.directives', []).
 directive('ncInitFocus', [function() {
  var timer;

  return function(scope, elm, attr) {
   if (timer) clearTimeout(timer);

   timer = setTimeout(function() {
    elm.focus();
    elm.select();
   }, 0);
  };
 }]);

elmが渡されるので、そこでDOM操作をする。 このDirectivesはフォーカスを設定して、全選択も行うようにしている。

2013年6月15日土曜日

Webリニューアル


Webサイトをリニューアルした。
今までのページは法人化する前に、今後はこんな感じで活動していければいいなと思って作ったものだった。そのときは、なるべく企業っぽくしたくないと思っていた。

今回はちょっと企業サイトみたいにしてみた。前回の記述も残っているので全面リニューアルではないが、デザインを含めて大きく変えてみた。

今回のリニューアルでAngularJSを使用している。Webアプリではないので、動的な箇所は多くないが、「Contact」のところなどは、ちょっとプログラムを書いてみた。
あとは、Tabs箇所もちょっと手を加えている。

Webサイトも継続的に開発していければと思うので、フィードバックを頂ければと思う。

http://www.nextcode.jp/

2013年6月14日金曜日

Windows Azure

Windows Azureで自社で使用するサーバーを運用している。
マイクロソフトが我々みたいなスタートアップを応援してくくれる、BizSparkというプログラムがあり、入会するとMSDNを提供してくれる。

その中にWindows Azureのサブスクリプションがあり、使用させてもらっている。

いわゆる、クラウドサーバーは、Google App EngineHerokuと使ってきたが今回はWindows Azureだ。

Windows Azureと名乗っているので、Windows Serverしか動かないとかと思ったが、実はLinuxも動かすことも出来るのだ。情報を一元化したかったので、使い慣れたRedmineを使用するため、Ubuntu Serverを使って導入してみた。

Google App EngineやHerokuと違って、仮想マシンを立ち上げるような感じだ。
仮想マシンが立ち上がった後は、sshでログインして設定を行う。Linuxサーバーらしく、コマンドラインでの管理がメインだ。
後は普通のサーバーと同じく、Rails入れて設定するだけ。

Google App EngineやHerokuと違って、使用していない時でも仮想マシンは停止されていないので、サービス起動を待つ必要がないのがいい。
各種リソース使用量を見ていると、もう1台サーバー使えそうだ。
MSDNといい、Windows Azureといい、マイクロソフトさんありがとうございます。






2013年6月12日水曜日

mapソフトのライセンス

Mapサービスを使ったアプリケーションを開発したい。
 技術習得の為Google Mapを使ってみたことはあるが、そんなに難しくなかったようだった。

しかし、各サービスにはライセンスがあり、それもよく改訂されている。自分の要件にあったものがあるか調べてみた。

今回は有料会員しか使えなかったり、イントラネットでの使用するなど閉じた環境を想定している。

Google Maps

「エンド ユーザーが自由にアクセスできる一般公開のサービスであれば、この API を利用できます」 とあり


  1. 有料の顧客のみがアクセス可能なサイト。
  2. 社内から、またはイントラネットでのみアクセス可能なサイト。
  3. 企業の配達業務、車両管理、企業資産管理に関連するアプリケーション、またはこれに類似するアプリケーション。


 となっており、今回の要件ではNGのようだ。別途有料で契約すればいいみたいだが。

Bing Maps

資料さがしましたが、日本語でライセンスを明示しているところを見つけられなかった。
英語はあったので頑張って読んでみたが、

“Limited Public Website Use” means using the Services for commercial, non-commercial or government use (provided that such use is not considered Education or Non-Profit Organization Use as defined in this section) under the TOU without entering into an Agreement, provided that (i) your use is consistent with the terms of Section 6; (ii) your Company Application is available on a public website; and (iii) you do not exceed 125,000 cumulative billable transactions (which will be free of charge) as defined in the SDKs, in any twelve month period.

6.    Limited Public Website Use. Subject to your compliance with Sections 1, 2, 6 and 8 of this TOU, you may develop or host a Company Application that uses the Services for Limited Public Website Use (as defined in Section 2). You may use the Services solely in conjunction with and integrated into Company Applications using only methods and means of access that are documented in the SDKs. If you will exceed the Limited Public Website Use transaction limits or limits on use of the Bing Spatial Data Services API, please contact us at maplic@microsoft.com to discuss how you can license additional transactions. Please note that we do not provide warranties for the Services for Limited Public Website Use under this Section 6. This TOU also limits our liability. These terms are in Sections 8.8 and 8.9 and we ask you to read them carefully.

こんな感じでやっぱり公開サイトでないとダメだと書いているように見える。
ここも参照させてもらったが、やっぱりNGのようだ。これも有料契約すればいける。

Yahoo! Japan

Yahoo! Japanさんの地図はYahoo! Open Local Platformと言うらしい。
これは明確に、「閉じた環境での使用は有料サービスです。」と書いていた。登録すれば商用利用もOKだと書いていたのですが、NGのようだ。

OpenStreetMap
 「自由な地図をみんなの手に」のOSM。
ライセンスはクリエーティブコモンズライセンス CC-BY-SA 2.0となっている。

やはり閉じた環境では、OSM一択となる。Yahoo! Open Local PlatformでもOSMが使えるようになっているようだ。

あとは、どこかのサービスと契約して有料で始めるのも選択肢としてあるかも。

2013年6月5日水曜日

Railsでdevelopmentとproductionでインクルードするスクリプトを変更

Railsで開発時と運用時でインクルードするjavascriptを変えたい。

そもそもなぜこのような事をしたいのかは、webアプリをjavascriptで書いているが、サーバーへのアクセスが必要なもときがあり、それにはurlを指定する必要がある。だけど、開発環境時ではローカルにあるサーバーにアクセスさせたいし、運用時には正式なサーバー
にアクセスさせたい。
これまでは、運用環境にデプロイするたびに手動でurlを変更していた。

この作業はいずれミスをするだろうし、何しろ面倒くさい。なので、urlなど環境ごとに可変の情報を集めておき、開発時にはインクルードし、運用時にはインクルードしないようにできないか。と考えた。

google先生に聞いたみたところ、stackoverflowでこれを見つけた。

まさしくこれがやりたかったこと。

application.html.erb

<%load_javascript %>

application_helper.rb

module ApplicationHelper

 def load_javascript
   if Rails.env.production?
     javascript_include_tag 'application'
   else
     javascript_include_tag 'application', 'devVars'
   end
 end

end

devVars.jsに開発用の情報を記載する。
注意事項は、app/assets/javascriptsにdevVar.jsを置くとapplicationと一緒にインクルードされてしまうので、別の場所に置く必要がある。
vendor/assets/javascriptsに置いてみたところうまくいった。
同じ事で悩んでいる人はいないのだろうか。
railsでこれがベストプラクティクスか知りたい。