今年一番のうれしい情報、ほんとうにありがとうございます!!!!!!!!! note.com
GitHubで.を押すとブラウザのVSCodeが開く
入社 4 ヶ月の私が初見コードでも開発のスタートダッシュを切る技術 - エムスリーテックブログ
GitHub では . を押すとブラウザ上の VSCode が開くので、そちらを利用してみるといいかもしれません。VSCode のキーボードショートカットや全体検索が手軽に利用できて便利です。 なお GitHub のブラウザの方も現在は発展しており、画面内で定義ジャンプも可能です。
まじだ…便利すぎる…
ありがとうございます!!!!!!!!!!!!!!!!!!!!!!
CodespacesでAngularで遊んでたけど放置しすぎて消えてしまって構築方法忘れてしまったときに見るメモ
- Blankのテンプレートを選択
- とりあえずnodeのバージョンを確認(
node -v
) - 最新のangular CLIをインストール(
npm install -g @angular/cli
) - Angularのバージョン確認(
ng --version
) - プロジェクト作って動くか確認(
ng new my-app
) - 動作確認(
ng serve --open
)
モンハンワイルズ 初心者ハンマー感想
今月頭のカプコンのセールで1000円くらいでワールド売ってたので買ってみた初心者の感想です。
ちなみにモンハンは3DSのやつしかやったことなくて、そのときはチャージアックス?使っていた。
- 力溜めなくなった
- 手癖になってたので、力溜めがなくなったことに気づくまで混乱した
- 手順が1個減ったと思えば良いことなんだけど手癖になってたので…
- クラッチクローなくなった
- 手癖になってたので…
- 初手クラッチクローで壁ドンもしくは傷だったのと、ハンマーは当てるまでの距離が短いので重宝してたのでなくなったのはショック
- 距離短くなった?
- ワールドの距離で当たらなくなった気がする(短い)
- 坂ぐるぐるもそもそも坂をワールドよりすべらなくなったり(滑るまでの時間が長い)わりとちゃんと距離を図らないと当たらなくなった(ワールドのガバで当たるのがなくなった?)
クラッチクローなくなったのがなあという感じなのと、傷をつけたら集中で攻撃ってことみたいなんだけど、L2+R1みたいないままで使ってなかったキーを押すというのが慣れてなくてわりとしんどいです。
ちなみにサブ武器を使えるようになったんだけど、ハンマーしか使ってなかったのでデフォの弓の弾切れしたあとのチャージの仕方がわからなくてすぐメインに戻しました。
MatTableのSortなにもわからない
Angular独特すぎていつまで経ってもよくわからないし、さらに輪をかけてAngular Materialもよくわからない
デザインが変わるからTailwindみたいなCSSフレームワークと同じ感覚で使ってしまっていてわけわからんって感じになっていて、そうじゃないと理解できると意味わかるという感じ
そういうCSSフレームワーク的な理解でMatTableにソート付けたくて難儀したってことをメモしていきたい
ソート付けるためには
テーブルにソート動作を追加するには、 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とはなにか
DataSourceを拡張したもので、クライアント側のデータ配列を受け入れ,フィルタリング,(MatSort を用いた)ソート,(MatPaginator を用いた)ページ分割をネイティブにサポートするデータソース
sortingDataAccessor をオーバーライドすることで、 ソートのカスタマイズが可能になります。 また、filterPredicate をオーバーライドすることで、 フィルタのカスタマイズも可能になります。これは、フィルタマッチのために行データをどのように文字列に変換するかを定義します。
注意: このクラスは使い始めるためのシンプルなデータソースです。 そのため、堅牢な国際化サポートやサーバーサイドのインタラクションのような、より高度なケースを扱うための機能は備えていません。 あなたのアプリがより高度な使用例をサポートする必要がある場合は、独自のDataSourceを実装することを検討してください。
要は、MatTableDataSourceにすると自動的にソートとかフィルタとかなにもしなくても実装してくれてるってこと?
やってみた
してくれるが、かなりクセがある
以下ソートのドキュメント Table | Angular Material
まず、
@ViewChild(MatSort) sort: MatSort;
これをやらないとソートしてくれない
こいつの説明が何もなく唐突にサンプルに出てくる
4oくんに聞いてみた
MatSort
は、Angular Materialのソート機能を提供するためのディレクティブです。MatTable
と組み合わせて使用することで、ユーザーがテーブルの列ヘッダーをクリックすることで、その列に基づいてテーブルのデータをソートできるようにします。
基本的な使い方
- 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>
- コンポーネントでのセットアップ:
@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が消えないので困っていた。
そんなわけある?と思ってググるとそんなわけあるようで、こんな記事を見つけた。
まさにこれなんだけど、2017年なのでさすがにv18にもなってそんなわけないだろうと思って下にスクロールしていくと現代でも解決してないようでした。
結局どうやって解決したかは以下。
<form [formGroup]="myForm" #formDirective="ngForm" (ngSubmit)="submitForm(formDirective)">
private submitForm(formDirective: FormGroupDirective): void { formDirective.resetForm(); this.myForm.reset(); }
なんでこうなるかの理由が以下にある
以下4oくんの解説
解説
1. novalidate
属性の必要性
- 要点: フォームに
novalidate
属性を付けないと、ブラウザのネイティブなバリデーションが働き、Angular の期待する動作と食い違うことがあります。novalidate
を使用することで、Angular のバリデーションロジックを優先し、予期せぬ動作を防ぐことができます。
2. Angular と DOM の相互作用
- 課題: Angular の
FormGroup
は、DOM イベント(フォームの送信やバリデーションの失敗)に関する情報を直接管理していません。FormGroup
は純粋な Angular の構造で、DOM API とは無関係です。- そのため、フォーム送信後に
FormGroup#reset()
を呼んでも、送信状態(submitted
のフラグ)がリセットされない場合があります。 - これは、Angular の
FormGroup
とFormGroupDirective
の役割分担によるものです。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
イベントサイクルを利用する場合は、NgForm
やFormGroupDirective
を利用してフォームの送信状態を管理する必要があります。- 具体的には、
NgForm
をコンポーネントに注入するか、FormGroupDirective
を使って DOM のフォームオブジェクトをresetForm()
でリセットします。これにより、DOM と Angular のフォーム状態が同期します。
- 具体的には、
まとめ
Angular でフォームのバリデーションと送信を適切に管理するためには、novalidate
の使用が推奨されます。これにより、ネイティブバリデーションによる予期せぬ動作を防ぎ、Angular のバリデーションロジックを優先させることができます。また、必要に応じて NgForm
や FormGroupDirective
を使ってフォームの状態を制御することが、最も確実な方法です。
この解説により、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の式で書けるようになった。
なんかまだasyncとかをPipeで使うようなやつは@forで使うとエラーになるっぽくて全部移行はできない気がするんだけどそれはまあどうでもよくて、VSCodeでPrettierの拡張入れて整形するとこんな感じになって非常につらくてどうしたもんかと思ったら、単にローカルにPrettierを入れればよかった。
詳しくはここみてください。
Prettierの拡張にもローカルにPrettier入れろと書いてあるのは知ってたんだけど、入れなくてもまあ動くので気にしなかったんだけど、ドキュメントはちゃんと読んでその通りにしろということをが勉強になってすごく良かったです。
しらない間にangularのinputでdisabledが効かなくなっていた
そうとうふるいangularを使ってきたので最近v18で遊んでたらinputのdisabledが効かなくて、GPTくんに聞いてもよくわからん答え返されるのでぐぐったら同じ現象出ていた
属性バインディングでもdisabledできるんだけど、再描画とかで結構バグって使いものにならないのでこれしかなさそう
this.form.controls.name.disable();
旅行用LM
諸事情で来月も旅行いくんですが、十年に一度くらいしか旅行いかない勢としては旅行のプラン考えるのもめんどいし、この時間つぎに何するかとかこの時間からできることなにかあるかとかそこにいくにはどうやっていくかとか交通手段どうするかとか考えるのめちゃくちゃめんどいので、あらかじめPDFとかで読み込ませてAIに聞くのがよさそうと思ったので週末やってみます!
昨日できたこと
- フィットボクシング
- 仕事
- 断酒
今日のメンタルポイント
- だめ
北海道
北海道
先週なのですが、n十年ぶりに北海道に行ってきました。早めの夏季休暇なのですが、行ったのは札幌と函館です。
まとめ
- 中国人めちゃめちゃいる(最近東京で感じたことないくらい中国人いる)
- でかいので移動が大変
- 交通網は揃ってる
- 旅行お金かかるね
- たのしさとの天秤にかけるとどちらが勝ってるかを考えちゃいけない
札幌よかったところ
- エスコンフィールドめちゃくちゃよい
- 1階外野席?だったんですが、めちゃくちゃ近くて(のように感じる(東京ドーム比))よい
- きつねダンスみれてよかった
- 地元民が普通に地元のチームを応援してるみたいな感じで客層が幅広い
- 野球見なくてもエスコンで飲み食いしたり探索するのもたのしい
- セイコーマートはレジ袋無料
- なぜかローソンめちゃくちゃ多い
- ローソンめちゃくちゃ多くて、次にファミマ、セブンほとんどみない
札幌いまいちだったところ
- エスコンフィールドめちゃくちゃ遠い
- 北広島から徒歩で行ったんですが、2kmくらいあるのでめちゃめちゃ遠い
- バスはピストンで往復してるぽいが、複数人ならタクシーで行ったほうが楽かも
- 札幌に宿を取ってると新千歳と札幌の間が北広島なので荷物持ちながら移動はつらすぎる
- 移動は日ハムの公式からチケット取るとクローク優先預かりのチケットも買える(500円)なので一緒に買って預けるのが楽かも(コインロッカー足りないらしいし探すの面倒すぎる)
- 飯がクソ高すぎる
- 観光地に総じて言えることだけどなにもかもが全部高い
- めったに行くことないから許容できたけど、持ち込みだめなので地元民が応援でこの値段で普通に飯と買ってるんだとしたら札幌民すごすぎる
- すすきのの治安やばすぎる(ように感じる東京の端っこ民)
- すすきののメインから1本入ったとこにホテル取ったんだけど、ホストクラブめちゃめちゃあってびっくりする
- あくまで個人の感想です
- すすきの年齢層が学生みたいなひとがめちゃめちゃおおい(おじさんおばさんほとんどみかけないくらい多く感じる)
- 中国人めちゃめちゃおおい
函館よかったところ
函館いまいちだったところ
- 中国人めちゃめちゃおおい
- 飯がクソ高すぎる
- 観光地に総じて言えることだけどなにもかもが全部高い
- 観光業なのでそういうもんだと思うんですが、朝市とか地元のひと行ってんのかなという価格帯
- どこ行ってもラッキーピエロある
- いまいちとは違うけど、どこいってもラッキーピエロある
印象的なのがすすきので、東京の西側いかないので歌舞伎町とか渋谷のほうがやばいのかもしれませんが、東側民なので東側のヤバエリアしかしらないのですが、わかいひとがめちゃめちゃおおくてびっくりしましたので、みなさんも北海道いきましょう。