みんなのちからになりたい

コピペでブログラムつくっていきたい

GitHubで.を押すとブラウザのVSCodeが開く

入社 4 ヶ月の私が初見コードでも開発のスタートダッシュを切る技術 - エムスリーテックブログ

GitHub では . を押すとブラウザ上の VSCode が開くので、そちらを利用してみるといいかもしれません。VSCode のキーボードショートカットや全体検索が手軽に利用できて便利です。 なお GitHub のブラウザの方も現在は発展しており、画面内で定義ジャンプも可能です。

まじだ…便利すぎる…

ありがとうございます!!!!!!!!!!!!!!!!!!!!!!

CodespacesでAngularで遊んでたけど放置しすぎて消えてしまって構築方法忘れてしまったときに見るメモ

  1. Blankのテンプレートを選択
  2. とりあえずnodeのバージョンを確認(node -v
  3. 最新のangular CLIをインストール(npm install -g @angular/cli
  4. Angularのバージョン確認(ng --version
  5. プロジェクト作って動くか確認(ng new my-app
  6. 動作確認(ng serve --open

モンハンワイルズ 初心者ハンマー感想

今月頭のカプコンのセールで1000円くらいでワールド売ってたので買ってみた初心者の感想です。

ちなみにモンハンは3DSのやつしかやったことなくて、そのときはチャージアックス?使っていた。

  • 力溜めなくなった
    • 手癖になってたので、力溜めがなくなったことに気づくまで混乱した
    • 手順が1個減ったと思えば良いことなんだけど手癖になってたので…
  • クラッチクローなくなった
    • 手癖になってたので…
    • 初手クラッチクローで壁ドンもしくは傷だったのと、ハンマーは当てるまでの距離が短いので重宝してたのでなくなったのはショック
  • 距離短くなった?
    • ワールドの距離で当たらなくなった気がする(短い)
    • 坂ぐるぐるもそもそも坂をワールドよりすべらなくなったり(滑るまでの時間が長い)わりとちゃんと距離を図らないと当たらなくなった(ワールドのガバで当たるのがなくなった?)

クラッチクローなくなったのがなあという感じなのと、傷をつけたら集中で攻撃ってことみたいなんだけど、L2+R1みたいないままで使ってなかったキーを押すというのが慣れてなくてわりとしんどいです。

ちなみにサブ武器を使えるようになったんだけど、ハンマーしか使ってなかったのでデフォの弓の弾切れしたあとのチャージの仕方がわからなくてすぐメインに戻しました。

MatTableのSortなにもわからない

Angular独特すぎていつまで経ってもよくわからないし、さらに輪をかけてAngular Materialもよくわからない

デザインが変わるからTailwindみたいなCSSフレームワークと同じ感覚で使ってしまっていてわけわからんって感じになっていて、そうじゃないと理解できると意味わかるという感じ

そういうCSSフレームワーク的な理解でMatTableにソート付けたくて難儀したってことをメモしていきたい

ソート付けるためには

Table | Angular Material

テーブルにソート動作を追加するには、 matSort ディレクティブをテーブルに追加し、ソートをトリガする各列ヘッダセルに mat-sort-header を追加します。 matSort ディレクティブを初期化するには、MatSortModule をインポートする必要があることに注意してください (API ドキュメントを参照してください)。

こういうこと

<table matSort (matSortChange)="sortData($event)">
  <tr>
    <th mat-sort-header="name">Dessert (100g)</th>
    <th mat-sort-header="calories">Calories</th>
    <th mat-sort-header="fat">Fat (g)</th>
    <th mat-sort-header="carbs">Carbs (g)</th>
    <th mat-sort-header="protein">Protein (g)</th>
  </tr>

やってみた

matSortやsort-header付けただけだと画面上なんの変更もない

MatSortModuleをimportすると矢印がつく(もちろんソートはされない)

テーブルのデータソースに MatTableDataSource を使用している場合、データソースに MatSort ディレクティブを指定すると、ソートの変更を自動的にリッスンし、テーブルによってレンダリングされるデータの順序を変更します。

デフォルトでは、MatTableDataSource は、ソートされた列の名前が、列が表示するデータ・プロパティ名と一致することを前提としてソートします。 例えば、以下の列定義は position という名前で、行セルに表示されるプロパティの名前と一致します。

MatTableDataSourceとはなにか

Table | Angular Material

DataSourceを拡張したもので、クライアント側のデータ配列を受け入れ,フィルタリング,(MatSort を用いた)ソート,(MatPaginator を用いた)ページ分割をネイティブにサポートするデータソース

sortingDataAccessor をオーバーライドすることで、 ソートのカスタマイズが可能になります。 また、filterPredicate をオーバーライドすることで、 フィルタのカスタマイズも可能になります。これは、フィルタマッチのために行データをどのように文字列に変換するかを定義します。

注意: このクラスは使い始めるためのシンプルなデータソースです。 そのため、堅牢な国際化サポートやサーバーサイドのインタラクションのような、より高度なケースを扱うための機能は備えていません。 あなたのアプリがより高度な使用例をサポートする必要がある場合は、独自のDataSourceを実装することを検討してください。

要は、MatTableDataSourceにすると自動的にソートとかフィルタとかなにもしなくても実装してくれてるってこと?

やってみた

してくれるが、かなりクセがある

以下ソートのドキュメント Table | Angular Material

まず、 @ViewChild(MatSort) sort: MatSort;これをやらないとソートしてくれない

こいつの説明が何もなく唐突にサンプルに出てくる

4oくんに聞いてみた


MatSortは、Angular Materialのソート機能を提供するためのディレクティブです。MatTableと組み合わせて使用することで、ユーザーがテーブルの列ヘッダーをクリックすることで、その列に基づいてテーブルのデータをソートできるようにします。

基本的な使い方

  1. HTMLのセットアップ: テーブルの各列ヘッダーにmat-sort-headerディレクティブを追加します。これにより、ソート機能が有効になります。
   <table mat-table [dataSource]="dataSource" matSort>
     <ng-container matColumnDef="name">
       <th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
       <td mat-cell *matCellDef="let element"> {{element.name}} </td>
     </ng-container>
     <!-- 他の列も同様に定義 -->
   </table>
  1. コンポーネントでのセットアップ: @ViewChildデコレーターを使って、MatSortインスタンスを取得し、それをデータソースに関連付けます。これにより、テーブルデータが自動的にソートされるようになります。
   import { Component, ViewChild } from '@angular/core';
   import { MatSort } from '@angular/material/sort';
   import { MatTableDataSource } from '@angular/material/table';

   @Component({
     selector: 'app-my-table',
     templateUrl: './my-table.component.html',
   })
   export class MyTableComponent {
     displayedColumns: string[] = ['name', 'age', 'address'];
     dataSource = new MatTableDataSource(ELEMENT_DATA);

     @ViewChild(MatSort) sort: MatSort;

     ngAfterViewInit() {
       this.dataSource.sort = this.sort;
     }
   }

### @ViewChildについて

  • @ViewChild(MatSort) sort: MatSort;は、AngularのViewChildデコレーターを使って、MatSortディレクティブのインスタンスを取得しています。
  • @ViewChildは、Angularがテンプレート内の特定のコンポーネントやディレクティブへの参照をコンポーネントクラスに注入するための機能です。この場合、MatSortディレクティブのインスタンスsortというプロパティに割り当てられます。
  • ngAfterViewInitライフサイクルフックでthis.dataSource.sort = this.sort;を設定することで、テーブルデータがMatSortと連携して動作するようになります。

なぜ@ViewChildが必要なのか

@ViewChildを使用する理由は、MatSortはテンプレート内に宣言されているため、コンポーネントクラス内で直接参照できないからです。@ViewChildを使うことで、テンプレートに存在するMatSortディレクティブをクラス内で操作できるようになります。

まとめ

MatSortを使用するためには、HTMLでmat-sort-headerを各列ヘッダーに追加し、コンポーネントクラスで@ViewChildを使ってMatSortを取得し、データソースに関連付ける必要があります。このプロセスにより、テーブル内のデータを簡単にソートできるようになります。

参考ページ: Angular Material Sort Overview


↑ テンプレに設定してるMatSort direvtiveにアクセスするためにViewChildがいるってことらしい

direvtiveってテンプレでしか使ったことなくて、directiveのメソッドにアクセスしてなんかしたいってことなかったから考えもしなかったど、こういうケースで使えるってことなのか、これはすごい勉強になる


this.dataSource.sort = this.sort;これをすることでソートされる


ここまでやってやっと気づいたのが、mat-tableとかこいつらディレクティブでコンポーネントでもなんでもないってことで、これ付けたらCSSが変わって見た目が変わるって理解しかしてなかったけど(まあそうなんだけど)、ディレクティブだから内部でよろしくやって見た目変えてたんだなと

これが理解できたらたしかに公式にちゃんと書いてあるわ…って感じであって、理解って大事だなと思いました

AngularのFormGroupでresetしてもmat-form-fieldのinvalidがリセットされない件

件名そのままなんだけど、submitしたあとにform.reset()してもinvalidが消えないので困っていた。

そんなわけある?と思ってググるとそんなわけあるようで、こんな記事を見つけた。

github.com

まさにこれなんだけど、2017年なのでさすがにv18にもなってそんなわけないだろうと思って下にスクロールしていくと現代でも解決してないようでした。

結局どうやって解決したかは以下。

mat-form-field does not remove mat-form-field-invalid class on FormGroup reset · Issue #4190 · angular/components

<form [formGroup]="myForm" #formDirective="ngForm" (ngSubmit)="submitForm(formDirective)">
private submitForm(formDirective: FormGroupDirective): void {
    formDirective.resetForm();
    this.myForm.reset();
}

なんでこうなるかの理由が以下にある

mat-form-field does not remove mat-form-field-invalid class on FormGroup reset · Issue #4190 · angular/components

以下4oくんの解説


解説

1. novalidate 属性の必要性

  • 要点: フォームに novalidate 属性を付けないと、ブラウザのネイティブなバリデーションが働き、Angular の期待する動作と食い違うことがあります。novalidate を使用することで、Angular のバリデーションロジックを優先し、予期せぬ動作を防ぐことができます。

2. Angular と DOM の相互作用

  • 課題: Angular の FormGroup は、DOM イベント(フォームの送信やバリデーションの失敗)に関する情報を直接管理していません。FormGroup は純粋な Angular の構造で、DOM API とは無関係です。
    • そのため、フォーム送信後に FormGroup#reset() を呼んでも、送信状態(submitted のフラグ)がリセットされない場合があります。
    • これは、Angular の FormGroupFormGroupDirective の役割分担によるものです。FormGroupDirective が DOM と連携し、FormGroup がその上に構築されています。

3. DOM イベントとフォーム送信の動作

  • フォーム送信イベントの動作: <form> タグに対して submit イベントが発生する際、ボタンやフィールド自体にはイベントが発生しません。これは、ブラウザのデフォルト動作に由来します。
    • <button> タグのデフォルトは type="submit" であり、novalidate を付けないとフォーム送信が行われ、ネイティブのバリデーションが実行されます。バリデーションに失敗した場合、フォームは送信されず、submit イベントも発生しません。

4. HTML の問題点

  • エラーの原因: <button> タグのデフォルト動作により、フォームが送信され、ネイティブなバリデーションが実行されます。これにより、FormGroupDirective で管理されている Angular のバリデーションとは別の動作が発生します。
    • これが、意図しないエラーメッセージやフォーム送信の原因となります。

5. エラーの解決策

  • ベストプラクティス: <form> タグに novalidate を付け、ボタンに type="button" を指定することで、フォーム送信を防ぐことができます。
    • <button mat-button type="button">ボタンラベル</button>
    • <input mat-button type="button" value="ボタンラベル">
    • これにより、ネイティブの submit イベントによる不具合を回避できます。

6. 例外的なケースへの対応

  • 特殊なケース: ネイティブの submit/invalid イベントサイクルを利用する場合は、NgFormFormGroupDirective を利用してフォームの送信状態を管理する必要があります。
    • 具体的には、NgFormコンポーネントに注入するか、FormGroupDirective を使って DOM のフォームオブジェクトを resetForm() でリセットします。これにより、DOM と Angular のフォーム状態が同期します。

まとめ

Angular でフォームのバリデーションと送信を適切に管理するためには、novalidate の使用が推奨されます。これにより、ネイティブバリデーションによる予期せぬ動作を防ぎ、Angular のバリデーションロジックを優先させることができます。また、必要に応じて NgFormFormGroupDirective を使ってフォームの状態を制御することが、最も確実な方法です。

この解説により、Angular フォームの内部で発生している複雑な相互作用と、それに伴う問題点をより深く理解できるでしょう。


novalidateはまあどうでもよくて、要は

  • FormGroup は純粋な Angular の構造で、DOM API とは無関係
  • なのでFormGroup#reset() を呼んでも、送信状態(submitted のフラグ)がリセットされない(場合があると書いてあるが実際にリセットされない)
  • FormGroupDirective は DOM と連携してるので、こいつでresetすればブラウザ動作のresetがされる(要はtype="reset"と同じ動作)(ViewChildでやってもたぶんいけると思う)

なので、FormGroupDirective 使ってFormをリセットしたらちゃんと動作した

Angular17 or 18のBuilt-in control flowをVSCodeで効かせるためにはローカルにPrettierを入れろ

古のAngularだとテンプレートに条件式を入れたい場合は

<div *ngIf="condition">Content to render when condition is true.</div>

みたいに書く必要があったのだけれど、v18から正式に現代のフレームワークで多く使われていると思われる@ifの式で書けるようになった。

angular.dev

なんかまだasyncとかをPipeで使うようなやつは@forで使うとエラーになるっぽくて全部移行はできない気がするんだけどそれはまあどうでもよくて、VSCodeでPrettierの拡張入れて整形するとこんな感じになって非常につらくてどうしたもんかと思ったら、単にローカルにPrettierを入れればよかった。

詳しくはここみてください。

stackoverflow.com

Prettierの拡張にもローカルにPrettier入れろと書いてあるのは知ってたんだけど、入れなくてもまあ動くので気にしなかったんだけど、ドキュメントはちゃんと読んでその通りにしろということをが勉強になってすごく良かったです。

しらない間にangularのinputでdisabledが効かなくなっていた

そうとうふるいangularを使ってきたので最近v18で遊んでたらinputのdisabledが効かなくて、GPTくんに聞いてもよくわからん答え返されるのでぐぐったら同じ現象出ていた

ryuzan03.hatenablog.com

属性バインディングでもdisabledできるんだけど、再描画とかで結構バグって使いものにならないのでこれしかなさそう

this.form.controls.name.disable();

旅行用LM

諸事情で来月も旅行いくんですが、十年に一度くらいしか旅行いかない勢としては旅行のプラン考えるのもめんどいし、この時間つぎに何するかとかこの時間からできることなにかあるかとかそこにいくにはどうやっていくかとか交通手段どうするかとか考えるのめちゃくちゃめんどいので、あらかじめPDFとかで読み込ませてAIに聞くのがよさそうと思ったので週末やってみます!

www.watch.impress.co.jp

昨日できたこと

  • フィットボクシング
  • 仕事
  • 断酒

今日のメンタルポイント

  • だめ

北海道

北海道

先週なのですが、n十年ぶりに北海道に行ってきました。早めの夏季休暇なのですが、行ったのは札幌と函館です。

まとめ

  • 中国人めちゃめちゃいる(最近東京で感じたことないくらい中国人いる)
  • でかいので移動が大変
    • 交通網は揃ってる
  • 旅行お金かかるね
    • たのしさとの天秤にかけるとどちらが勝ってるかを考えちゃいけない

札幌よかったところ

  • エスコンフィールドめちゃくちゃよい
    • 1階外野席?だったんですが、めちゃくちゃ近くて(のように感じる(東京ドーム比))よい
    • きつねダンスみれてよかった
    • 地元民が普通に地元のチームを応援してるみたいな感じで客層が幅広い
    • 野球見なくてもエスコンで飲み食いしたり探索するのもたのしい
  • セイコーマートはレジ袋無料
  • なぜかローソンめちゃくちゃ多い
    • ローソンめちゃくちゃ多くて、次にファミマ、セブンほとんどみない

札幌いまいちだったところ

  • エスコンフィールドめちゃくちゃ遠い
    • 北広島から徒歩で行ったんですが、2kmくらいあるのでめちゃめちゃ遠い
    • バスはピストンで往復してるぽいが、複数人ならタクシーで行ったほうが楽かも
      • 札幌に宿を取ってると新千歳と札幌の間が北広島なので荷物持ちながら移動はつらすぎる
      • 移動は日ハムの公式からチケット取るとクローク優先預かりのチケットも買える(500円)なので一緒に買って預けるのが楽かも(コインロッカー足りないらしいし探すの面倒すぎる)
    • 飯がクソ高すぎる
      • 観光地に総じて言えることだけどなにもかもが全部高い
      • めったに行くことないから許容できたけど、持ち込みだめなので地元民が応援でこの値段で普通に飯と買ってるんだとしたら札幌民すごすぎる
  • すすきのの治安やばすぎる(ように感じる東京の端っこ民)
    • すすきののメインから1本入ったとこにホテル取ったんだけど、ホストクラブめちゃめちゃあってびっくりする
    • あくまで個人の感想です
      • すすきの年齢層が学生みたいなひとがめちゃめちゃおおい(おじさんおばさんほとんどみかけないくらい多く感じる)
      • 中国人めちゃめちゃおおい

函館よかったところ

  • 観光地わりと空いてる
    • 函館山のロープウェイ除く
    • 温泉安い
  • ラッキーピエロ
    • 個人的に唯一納得できる価格帯(バーガーセットしか食ってませんが)

函館いまいちだったところ

  • 中国人めちゃめちゃおおい
    • 函館山のロープウェイ地獄(民度というか国民性の違いを感じる)
  • 飯がクソ高すぎる
    • 観光地に総じて言えることだけどなにもかもが全部高い
    • 観光業なのでそういうもんだと思うんですが、朝市とか地元のひと行ってんのかなという価格帯
  • どこ行ってもラッキーピエロある

印象的なのがすすきので、東京の西側いかないので歌舞伎町とか渋谷のほうがやばいのかもしれませんが、東側民なので東側のヤバエリアしかしらないのですが、わかいひとがめちゃめちゃおおくてびっくりしましたので、みなさんも北海道いきましょう。