削除したリモートブランチがローカルで表示される場合

# リモートのブランチを表示
git branch --remote

# リモートに存在しない(削除された)ブランチを削除
git fetch --prune 

Angularでi18n

Angular CLI環境でアプリケーションのi18n対応をしました。

準備

翻訳対象(HTMLのタグ)にi18n属性を設定

<h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
  • i18n=<meaning>|<description>@@<id>
  • 値は必須ではない
  • メンテナンスを考慮した場合、IDは入力しておいた方がいい(未入力の場合、メッセージがかわるとIDも変わってしまうので)

XLIFF出力例

<trans-unit id="introductionHeader" datatype="html">
  <source>Hello i18n!</source>
  <context-group purpose="location">
    <context context-type="sourcefile">app/app.component.ts</context>
    <context context-type="linenumber">4</context>
  </context-group>
  <note priority="1" from="description">An introduction header for this sample</note>
  <note priority="1" from="meaning">site header</note>
</trans-unit>

要素を追加しない方法

<!--i18n: optional meaning|optional description -->
I don't output any element either
<!--/i18n-->

属性値を翻訳

<img [src]="logo" i18n-title title="Angular logo">

複数形、代替テキスト

(あとで確認する)

ファイル(XLIFF)の書き出し

Angular CLI利用している場合。

ng xi18n --output-path src/locale

XLIFFファイルについて

In the real world, you send the messages.es.xlf file to a Spanish translator who fills in the translations using one of the many XLIFF file editors.

https://angular.io/guide/i18n#translate-text-nodes

Serve

ng serve --aot --locale en --i18n-format xlf --i18n-file src/locale/messages.en.xlf

  • --i18n-file Localization file to use for i18n.
  • —i18n-format Format of the localization file specified with –i18n-file.
  • —locale Locale to use for i18n.

Note: this only works for AOT, if you want to use i18n in JIT you will have to update your bootstrap file yourself.

https://github.com/angular/angular-cli/wiki/stories-internationalization#serve

Build

ng build -prod --output-path dist/en --locale en --i18n-format xlf --i18n-file src/locale/messages.en.xlf

  • 基本はServeと同じ
  • --output-path dist/enを追加
    • 出力先を変更

Report missing translations

(あとで確認する)

参考

Remove all ads

(WIP) NgUpgradeのドキュメント読む

読んだドキュメント

実際に利用したか

  • すみません。自分たちのプロジェクトには利用していません。

理由

  • しばらくは大きな改善や機能追加がなさそうなので、移行作業に集中する時間を確保できそうだった。
    • これが主な理由
  • 今のAngularJSアプリケーションにAngularを導入することは結構簡単。ただ、同時にアップデートしたいことがいくつかあった。
    • Angualr CLI環境にしたい
    • 利用しているCSSフレームワークをアップデートしたい
    • UI RouterからAngular Routerに変更したい
  • 多言語対応しているアプリなので、対応が面倒になりそう。
    • (そうでもないかもしれない。この時点であまり深く考えなくなった。)

以下メモです。

NgUpgrade in Depth

NgUpgrade in Depth – nrwl

Bootstrapping

This is a good default because components upgraded from AngularJS to Angular require an AngularJS ancestor component, and this way of bootstrapping guarantees that.

コンポーネントツリーの上流にAngularJSコンポーネントが必要。

Capturing AngularJS and Lazy Loading

“@angular/upgrade/static” captures window.angular.

import 'angular';
import { UpgradeModule } from '@angular/upgrade/static';

angularを先に読み込む必要がある。

Component Integration

This creates an AngularJS directive with the appRoot selector. This directive will use AppComponent to render its template. Because of this indirection, we need to register AppComponent as an entry component.

(AngularJSにするコンポーネントをエントリーコンポーネントに登録する理由)

So the <app-root> element itself is owned by AngularJS, which means that we can apply other AngularJS directives to it. Its template, however, is rendered using Angular.

したがって、<app-root>要素自体はAngularJSによって所有されています。つまり、他のAngularJSディレクティブを適用することができます。ただし、そのテンプレートはAngularを使用してレンダリングされます。

UI Routerの場合

GitHub - ui-router/angular-hybrid: Upgrade an ng1 UI-Router app to a ng1+ng2 hybrid using ng-upgrade

We currently support routing either Angular (2+) or AngularJS (1.x) components into an AngularJS (1.x) ui-view. However, we do not support routing AngularJS (1.x) components into an Angular (2+) ui-view.

現在Angular(2+)またはAngularJS(1.x)コンポーネントをAngularJS(1.x)UIビューにルーティングしています。ただし、AngularJS(1.x)コンポーネントをAngular(2+)UIビューにルーティングすることはサポートしていません。

ルーターを利用する場合

記事ではルータを利用していない。実際のアプリケーションでは以下対応が必要。

Component Router does not work with Upgrade Adapter · Issue #9870 · angular/angular · GitHub

export class AppComponent implements OnInit {
  constructor(
    router: Router
  ) {
    router.initialNavigation();
  }
  // ...
}

Angular - Upgrading from AngularJS

Angular Docs

  • バージョン違いのコンポーネントをどのように両立、橋渡しするか
  • テンプレートの中の世界(AngularJSなのかAngualrなのか)は、そのコンポーネントが何でつくられているかによる
  • 「アップグレードする、ダウングレードするとは、対象のテンプレート内で利用できるようにすること」と考えるとすっきりする

The DOM element <a-component> will remain to be an AngularJS managed element, because it’s defined in an AngularJS template. That also means you can apply additional AngularJS directives to it, but not Angular directives. It is only in the template of the <a-component> where Angular steps in. This same rule also applies when you use AngularJS component directives from Angular.

DOM要素<a-component>は、AngularJSテンプレートで定義されているため、AngularJSが管理する要素のままです。 つまり、AngularJSディレクティブを追加できますが、Angularディレクティブは適用できません。 <a-component>のテンプレートにのみ、Angularが入る。これは、AngularのAngularJSコンポーネントディレクティブを使用する場合にも適用されます。

Note that you do not add a bootstrap declaration to the @NgModule decorator, since AngularJS will own the root template of the application.

AngularJSはアプリケーションのルートテンプレートを所有するためbootstrap、@NgModuleデコレータに宣言を追加しないことに注意してください。

TSlintで、特定ファイルや特定行のみ設定を変更したい

ライブラリやレスポンスデータの関係で対応が難しい場合や、他環境にあったファイルを一旦そのまま利用したい場合などに。

https://palantir.github.io/tslint/usage/rule-flags/

// ファイル全体に以下設定を反映
/* tslint:disable:no-null-keyword */
// 次の行のみ、以下設定を反映
/* tslint:disable-next-line:directive-selector */

Highchartsメモ

これは何か

毎回設定方法を忘れるので、逆引き的なメモを残しておきます。

基本

レシピ

(実際に動くサンプルは一番下にあります)

legendを外したい (c-1)

const config = {
  legend: {
    enabled: false
  },
  // ...
};

高さを変更したい (c-1)

const config = {
  chart: {
    // null(初期値)の場合、描画対象のcontainerの高さが利用される
    // containerの高さが設定されてない場合は400pxになる
    height: '200px'
  },
  // ...
};

crosshair(照準線)を表示 (c-1)

const config = {
  xAxis: {
    crosshair: {
    }
  },
  // ...
};

タイトルを非表示にする (c-2)

const config = {
  title: {
    // 空文字を設定
    text: ''
  },
  // ...
};

Axisを非表示にする (c-2)

const config = {
  xAxis: {
    visible: false
  },
  yAxis: {
    visible: false
  },
  // ...
};

どのAxisタイプを利用すべきか

Categories are groups of items, like for example “Apples”, “Pears” and “Oranges”, or “Red”, “Green”, “Blue”, “Yellow”. These categories have that in common that there are no intermediate values.

If you find that you can skip category labels by the xAxis.labels.step option, chances are that you are better off using a linear or datetime axis.

An xAxis of the linear or datetime type has the advantage that Highcharts is able to determine how close the data labels should be because it knows how to interpolate. The labels will by default be placed with approximately 100px between them, which can be changed in the tickPixelInterval option. If you have predictable categories like “Item1”, “Item2”, “Item3” or “2012-01-01”, “2012-01-02”, “2012-01-03” etc., linear or datetime axis types combined with an xAxis.labels.formatter would probably be a better choice.

Axisに日付を利用したい

  • http://api.highcharts.com/highcharts/xAxis.type
    • The type of axis. Can be one of linear, logarithmic, datetime or category. In a datetime axis, the numbers are given in milliseconds, and tick marks are placed on appropriate values like full hours or days. In a category axis, the point names of the chart’s series are used for categories, if not a categories array is defined. Defaults to linear.

Axisのタイプにdatetimeを設定 (c-3, c-4)

pointStart, pointIntervalを利用

const config = {
  xAxis: {
    type: 'datetime',
  },
  plotOptions: {
    series: {
      pointStart: Date.UTC(2010, 0, 1),
      pointInterval: 24 * 3600 * 1000 // one day
    }
  },
  // ...
};

seriesのdataでx valueを設定
https://www.highcharts.com/docs/chart-concepts/series

const config = {
  xAxis: {
    type: 'datetime',
  },
  series: [{
    name: 'Jane',
    data: [
      [Date.UTC(2010, 0, 1), 1],
      [Date.UTC(2010, 0, 2), 0],
      [Date.UTC(2010, 0, 3), 4]
    ]
  }, {
    name: 'John',
    data: [
      [Date.UTC(2010, 0, 1), 5],
      [Date.UTC(2010, 0, 2), 7],
      [Date.UTC(2010, 0, 3), 3]
    ]
  }]
  // ...
};

Axisのタイプにcategoryを設定 (c-5)

const config = {
  xAxis: {
    categories: [
      '2010-01-01',
      '2010-01-02',
      '2010-01-03',
    ],
  },
  // ...
};

背景部分にテキスト、文字、ラインを表示(非表示)したい (c-6, c-7, c-8)

const config = {
  yAxis: {
    // 横線を隠す
    gridLineWidth: 0
  },
  // ...
};
const config = {
  xAxis, {
    // 特定エリアに塗りとテキストと追加
    plotBands: [{
      color: 'rgba(0,0,255,.05)',
      from: -0.5,
      to: 0.5,
      label: {
        text: 'test'
      }
    }],
  // ...
};
const config = {
  xAxis, {
    // 特定の位置にラインを追加
    plotLines: [{
      color: '#f00',
      value: 0.5,
      width: 2,
    }],
  // ...
};
const config = {
  xAxis, {
    // xAxisにもグリッドラインを追加
    gridLineWidth: 2,
    tickInterval:1,

    // この設定は状況に合わせて(カテゴリーかどうか)
    tickmarkPlacement: 'on',
  // ...
  }
};

c-0 - c-2

c-3 - c-5

c-6 - c-8

FlexboxとAuto marginを組み合わせる

f:id:ryotah:20170721204657p:plain

こんな感じでコンテンツを左右(上下)に配置する時に便利。


以下のような問題(仕様)があるので、Flexboxを入れ子にした場合かつ、上下揃えをした場合は注意が必要。
css - Chrome / Safari not filling 100% height of flex parent - Stack Overflow

f:id:ryotah:20170721210737p:plain

  • キャプチャの左がChrome、右はSafari
  • 一番左のパターンは「Flexboxで伸びている高さ = height: 100%」という前提のもの
    • Chromeでは動く。ただしflex-basisを0にしないとこのような結果にはならない
  • 二番目はposition: absoluteを利用
  • 三番目はheight: 100%を利用せずにflex-growを活用するパターン
    • これがよさそう

ブロック要素にリンク(a tag)をつける

  1. ブロック要素内のaタグを、要素いっぱいに広げる
    • text-indent: -999px; などでテキストを非表示にする必要がある
  2. シンプルにaタグでブロック要素を包む
    • ブロック要素内のテキストがリンクテキストと同じスタイルにならないように調整する(必要ならば)
    • a { color: inherit; text-decoration: none; } など