Ionic パスワードの show/hide を実装（Angular）

#はじめに
イメージはこんなん

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Ionic password show/hide いい感じにできた！ <a href="https://t.co/irXqCueE5u">pic.twitter.com/irXqCueE5u</a></p>&mdash; 高卒プログラマーげんと (@gento34165638) <a href="https://twitter.com/gento34165638/status/1326507012402810881?ref_src=twsrc%5Etfw">November 11, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


#全体像
①auth.page.html
②auth.page.ts
③auth.service.ts

**※「auth」はAuthentication（認証）の略**

パスワードの show/hide にはこの３つのファイルを使う。

パスワードshow/hideが１箇所しかないのなら、別にserviceを使う必要はないかと。。。
ただ、私が運営してるアプリでは、「ログインページ」「サインインページ」「匿名ログインからのサインインページ」で３箇所にパスワードshow/hideを使いたかったので、serviceを使うことにした。

それでは、一気にコードを載せていきます！

#html

```html:auth.page.html
 <ion-item class="ion-margin-bottom">
          <ion-label position="floating">
              <ion-icon name="key"></ion-icon>パスワード
            </ion-label>
              <ion-input 
              required
              [(ngModel)]="login.password"
              [type]="showPassword ? 'text' : 'password'"
              name="login.password"
              #passwordCtrl="ngModel"
              minlength="6">
              </ion-input>
              <ion-icon class="passwordIcon" slot="end" [name]="passwordToggleIcon"
              (click)="togglePassword()"></ion-icon>
          </ion-item>

     <ion-item *ngIf="!passwordCtrl.valid && passwordCtrl.touched" lines="none">
            <ion-label color="danger">パスワードは6文字以上</ion-label>
         </ion-item>
```

パスワードのバリデーション部分は、この記事では説明を省くので下記を参考に:point_down:
[ionic フォームで変なこと書いてないか、バリデーションを実装](https://qiita.com/kokogento/items/e1e152814153c21936fe)

###余談
```html
 <ion-label position="floating">

 <ion-icon class="passwordIcon" slot="end" [name]="passwordToggleIcon"
              (click)="togglePassword()"></ion-icon>
```

ion-labelで`position="floating"`を使った場合、目のアイコンの位置が妙に高くなった。。
なので、global.cssに以下のようなcssを追加した。。。

```css:global.css
// パスワード隠すアイコンを無理やりinputの中央に
.passwordIcon {
  margin-top: 30px;
}
```

#tsファイル
※コードは必要最小限しか載せていません

```typescript:auth.page.ts
import { AuthService } from './auth.service';

export class AuthPage implements OnInit {

  showPassword: boolean;
  passwordToggleIcon = '';

constructor(
    private authService: AuthService,
  ) { }

ngOnInit() {
    this.showPassword = false;
    this.passwordToggleIcon = 'eye';
   }

// 必要な値を全てserviceに渡して処理
togglePassword() {
    this.showPassword = this.authService.togglePassword(this.showPassword);
    this.passwordToggleIcon = this.authService.changePasswordIcon(this.passwordToggleIcon);
  }
}
```


#service

```typescript
@Injectable({
  providedIn: 'root',
})
export class AuthService {

  showPassword = false;
  passwordToggleIcon = 'eye';

togglePassword(showPassword: boolean) {
    this.showPassword = !showPassword;
    return this.showPassword;
  }

changePasswordIcon(passwordToggle: string) {
    if (passwordToggle === 'eye') {
      this.passwordToggleIcon = 'eye-off';
      return this.passwordToggleIcon;
    } else {
      this.passwordToggleIcon = 'eye';
      return this.passwordToggleIcon;
    }
  }

}
```



#参考
https://www.youtube.com/watch?v=oIcgaAV8FIk

ほぼまるパクリしました:relieved:
serviceを使った場合、関数を２つに分けた方がわかりやすいと思ったのでこんな形となりました。。。