2018年11月11日日曜日

Angular ngModel 使い方

Angular の ngModel の使い方をメモしておきます。黄色でハイライトされている部分を追加すると ngModel を利用できるようになります。

1.app.module.ts

ngModel は angular/forms の FormsModule に含まれているので、FormsModule をインポートします。また、NgModel デコレータの imports で FormsModule をインポートします。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule }   from '@angular/forms';//追加

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule//追加
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

2.app.component.html

HTML テンプレートで ngModel に変数 name をバインドします。
<input type="text" [(ngModel)]="name">
{{name}}

3.app.component.ts

変数 name の初期値を設定します。
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';
  name = 'sasaki';//追加
}

2018年10月7日日曜日

ASP.NET Core Web API - html ファイルの利用

ASP.NET Core Web API で html ファイルを利用(表示)する方法です。

Startup.cs ファイルの Configure メソッドに、app.UseStaticFiles() を呼び出します。すると、wwwroot フォルダ配下の html ファイルを表示できるようになります。

public class Startup
{
    ...

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseMvc();
        app.UseStaticFiles(); //追加
    }
}

ASP.NET Core Web API - GET と POST

ASP.NET Core Web API で GET メソッドと POST メソッドの実装方法を調べてみました。


ValuesController.cs (一部抜粋)
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // POST api/values
    [HttpPost]
    public void Post([FromBody] string id)
    {
    }
}

index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <input type="button" value="click" onclick="get()" />
    <input type="button" value="post" onclick="post()" />
    <script>
        function get(){
            var httpRequest = new XMLHttpRequest();
            httpRequest.onreadystatechange = function () {
                if (httpRequest.readyState === 4) {
                    if (httpRequest.status === 200) {
                        console.log("GET: 通信成功");
                    } else {
                        console.log("GET: 通信失敗");
                    }
                }
            };
            httpRequest.onload = function () {
                console.log("GET: 通信完了");
            };
            httpRequest.open("GET", "api/values", true);
            httpRequest.send(null);
        }

        function post() {
            var httpRequest = new XMLHttpRequest();
            httpRequest.onreadystatechange = function () {
                if (httpRequest.readyState === 4) {
                    if (httpRequest.status === 200) {
                        console.log("POST: 通信成功");
                    } else {
                        console.log("POST: 通信失敗");
                    }
                }
            };
            httpRequest.onload = function () {
                console.log("POST: 通信完了");
            };
            
            httpRequest.open("POST", "api/values", true);
            httpRequest.setRequestHeader('Content-Type', 'application/json');
            httpRequest.send(JSON.stringify("id=abc"));
        }
    </script>
</body>
</html>

POST を行うときには、setRequestHeader で Content-Type に application/json を指定する必要があります。ここが分からなくてしばらく調べました。

2018年9月22日土曜日

Flexbox を利用して要素を中央と右端に表示

Flexbox を利用して、要素を中央と右端に表示してみます。
parent クラスで display: flex としているので、justify-content に center とすることで、子要素(メインアイテム)を中央表示にしています。

item クラスで position: absolute としているので、子要素(メニュー)は 常に右端にくっついています。また、parent クラスで position: relative としているので、子要素(メニュー)は親要素の中で絶対位置の計算が行われます。

イメージ



CSS

<style>
    .parent {
        position: relative;
        display: flex;
        justify-content: center;

        border: black solid 1px;
        padding: 20;
    }

    .item {
        display: flex;

        margin: 3px;
        padding: 15px;
        border: black solid 1px;
    }

    .menu {
        position: absolute;
        right: 0;

        margin: 3px;
        padding: 15px;
        border: black solid 1px;
    }
</style>

HTML

<div class="parent">
    <div class="item">メインアイテム</div>
    <div class="item">メインアイテム</div>
    <div class="menu">メニュー</div>
</div>

2018年9月17日月曜日

JavaScript ネイティブの Promise を利用する方法

JavaScript ネイティブの Promise を利用する方法を調べてみました。備忘録のためメモしておきます。

処理が成功したら resolve メソッドを呼びます。処理が失敗したら、reject メソッドを呼びます。reject メソッドを呼ぶと、catch 句に入ります。

function myTest() {
  const promise = new Promise((resolve, reject) => {
      setTimeout(() => {
          console.log('スタート');
          //処理が成功したら、resolve を呼ぶ。
          resolve('1つ目の処理');
      }, 1000);

  });
  promise.then((message) => {
      return new Promise((resolve, reject) => {
          setTimeout(() => {
              console.log(message);
              resolve('2つ目の処理');
              //エラーの場合、resolve ではなく reject を呼ぶ。
              // reject('xxx');

          }, 300);

      })
  }).then((message) => {
      return new Promise((resolve, reject) => {
          console.log(message);
          console.log('3つ目の処理');
      })
  }).catch((error) => { // エラーの場合
      console.error('エラー', error);
  });
}

2018年9月16日日曜日

Flexbox を利用してレスポンシブなレイアウトを実現する

タイトルのままです。Flexbox を利用して 2 カラムのレスポンシブレイアウトを実現する例です。コピペしてそのまま使えますので、よかったら使ってみてください。

CSS
.header{
    background: lightpink;
    height: 40px;
    width: 100%;
}
.parent{
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 90vh;
}
.main{
    background: lightblue;
    height: 50%;
 }
.sidebar{
    background: lightseagreen;
    height: 50%;
}
@media screen and (min-width : 768px) { /* デスクトップ用 CSS */
    .parent{
        flex-direction: row;
    }
    .main{
        flex: 1;
        height: 100%;
    }
    .sidebar{
        width: 250px;
        height: 100%;
    }
}

HTML
<div class="header">header</div>
<div class="parent">
    <div class="main">item 1</div>
    <div class="sidebar">item 2</div>
</div>


2018年9月15日土曜日

Flexbox を使って要素を並べる

Flexbox を利用して、要素を横並び、縦並びにする方法です。

横並び

リストの親要素(div class="list") の display に flex を指定します。そして、リストの子要素に flex を指定します。ここでは flex: 1 1 としています。
.list {
    display: flex;
}
.list-item {
    flex: 1 1;
    border: solid cadetblue 1px;
}

<div class="list">
    <div class="list-item">item 1</div>
    <div class="list-item">item 2</div>
    <div class="list-item">item 3</div>
</div>

縦並び

縦並びは、リストの親要素(div class="list") の display-direction に column を指定します。
.list {
    display: flex;
    flex-direction: column;
}
.list-item {
    flex: 1 1;
    border: solid cadetblue 1px;
}

<div class="list">
    <div class="list-item">item 1</div>
    <div class="list-item">item 2</div>
    <div class="list-item">item 3</div>
</div>

2018年9月7日金曜日

要素を画面の下部に表示する方法

HTML と CSS で、要素を画面の下部に表示する方法です。
CSS で position を fixed、bottom に 0px とします。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
    .bottom {
        position: fixed;
        bottom: 0px;
        background: red;
        height: 40px;
        width: 100px;
    }
    </style>
</head>
<body>
    <div class="bottom">テキスト</div>
</body>
</html>

2018年8月27日月曜日

入門:セマンティックマークアップで役に立ったリンク集

HTML5の文書構造「セマンティックマークアップ」まとめ
https://bsj-k.com/html5-semantic-markup/

→ 端的な説明で、セマンティックタグの説明をしてくれています。概要理解にとてもいいと思いました。


実践!すぐに導入できるセマンティックなマークアップ、4つのパターン
https://thinkit.co.jp/story/2012/04/25/3536

→ article は「自己完結型のコンテンツを配置する」という説明を見かけますが、いまいちピンと来ていませんでした。こちらの記事では、RSS フィードの例でわかりやすく説明してくれています。


HTML5.1を使ってSEOに強いセマンティックコーディングをする方法
https://fastcoding.jp/blog/all/html5toseo/

→ 「3. HTML5タグの正しいセクショニングを設定する」では、図解で分かりやすくタグの構成を解説してくれています。

2018年7月28日土曜日

Angular - ngIf ディレクティブ

Angular の ngIf ディレクティブの利用例です。

HTML テンプレート
<p>
  <input type="button" value="toggle flag" (click)="toggleFlag()">
</p>

<div #ifBlock *ngIf="flag; else elseBlock">
  This is ifBlock
</div>

<ng-template #elseBlock>
  Here is elseBlock.
</ng-template>

TypeScript
export class IfComponent implements OnInit {

  flag: boolean;


  constructor() { }

  ngOnInit() {
    this.flag = true;
  }


  toggleFlag(){
    this.flag = !this.flag;
  }
}
TypeScript の flag 変数の値に応じて表示します。flag 変数の値が true のときは #ifBlock のある div タグが、false のときは #elseBlock のある ng-template の中が表示されます。

2018年6月6日水曜日

Angular 関連メモ

Angular CLI を利用した、プロジェクトへの各種機能の追加

コンポーネントの生成
D:\dev\angular\app1\src\app>ng g c comp1
→ コンポーネントは、app.component.html にタグとして定義して、画面に埋め込む。
app フォルダ配下でコマンドを実施する点は注意。

サービスの生成
ng g s service1

2018年5月2日水曜日

ASP.NET MVC 5 学習リソース

ASP.NET MVC の学習で役に立ったリソースの一覧です。

ASP.NET MVC5実践プログラミング
https://www.amazon.co.jp/dp/4798041793

プログラミングMicrosoft ASP.NET MVC 第3版
https://www.amazon.co.jp/dp/4822298388

The Complete ASP.NET MVC 5 Course(英語)
https://www.udemy.com/the-complete-aspnet-mvc-5-course/

2018年4月21日土曜日

ASP.NET MVC で URL からコントローラー名を隠す

2018/04/23 追記
ふと、属性ルーティングで済むのではないかと思い、試してみました。結果、うまくいきました。

RegisterRoutes 内で、MapMvcAttributeRoutes を呼び出します。デフォルトで定義されている MapRoute は、必要がなければ削除(コメントアウト)します。
public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        //属性ルーティングの有効化
        routes.MapMvcAttributeRoutes();

        //"Home" や "Home/Index" にアクセスする必要がなければ削除
        //routes.MapRoute(
        //    name: "Default",
        //    url: "{controller}/{action}/{id}",
        //    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        //);
    }
}

続いて、ルート属性を利用して、指定します。ルートの ”/”、”/Articles”、”/Articles/Index” で Index アクションにアクセスできるように属性を 3 つ設定しています。
public class ArticlesController : Controller
{
    [Route("~/")]
    [Route("Articles")]
    [Route("Articles/Index")]
    public ActionResult Index()
    {
        return View();
    }
}

しかも、最初に参照していた stackoverflow のスレッドにも、この属性ルーティングの方法が提案されていました。よく読みましょう... (^^;)
https://stackoverflow.com/a/39948890


2018/04/22
タイトルのままです。ASP.NET MVC で URL からコントローラー名を隠す方法を調べてみました。結果、ルーティングを設定することで解決しました。

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        //MyRoute を追加。コントローラー名を指定していないリクエストは、Articles コントローラーで捕捉
        routes.MapRoute(
            "MyRoute",
            "{action}/{id}",
            new
            {
                controller = "Articles",
                action = "Index",
                id = UrlParameter.Optional
            }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

参考:ASP.NET MVC - Removing controller name from URL
https://stackoverflow.com/questions/3337372/asp-net-mvc-removing-controller-name-from-url

2018年3月27日火曜日

ASP.NET Web API で JSON を返す方法

ASP.NET Web API で JSON を返す実装例です。

1.WebApiConfig クラス内で "text/html" フォーマットをリターンするようにします。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API の設定およびサービス
        ...

        //json を返す
        //https://stackoverflow.com/a/13277616
        config.Formatters.JsonFormatter.SupportedMediaTypes
            .Add(new MediaTypeHeaderValue("text/html"));
    }
}

2.Request.CreateReponse メソッドに、ステータスコードと、モデルのリストを渡します。すると、クライアントには JSON がリターンされます。

public class ProductsController : ApiController
{
    ...

    public HttpResponseMessage Get()
    {
        IList<IProduct> products = _rep.GetAll();

        //モデルリストから JSON に変換
        //Content Negotiation in ASP.NET Web API
        //https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/content-negotiation#serialization
        return Request.CreateResponse(HttpStatusCode.OK, products);
    }
}

2018年3月26日月曜日

論理回路

AND 条件・・・2つのスイッチを直列につないで、両方のスイッチが押されて電気が流れる

OR 条件・・・2つのスイッチを並列につないで、どちらか一方のスイッチが押されて電気が流れる

NOT 条件・・・スイッチを押すと電気が流れなくなる

2018年2月4日日曜日

Angular5 TODO リスト作成

Angular5 で簡易な TODO リストを作成する実装例を紹介します。

環境準備

node.js 及び npm のインストール

Angular によるアプリケーション開発を行うにあたり、これら機能を利用しますので、それぞれインストールします。インストール後、バージョンを確認します。

バージョン確認
node -v
npm -v

Angular インストール

次のコマンドで Angular CLI をインストールします。
npm install @angular/cli -g


Angular バージョ確認
ng -v


Angular CLI プロジェクトの作成、及びアプリケーションの起動

次のコマンドで Angular CLI プロジェクトを作成します。
ng new todoApp

作成したアプリケーションフォルダに移動
cd todoApp

アプリケーション起動
ng serve -o

→ ブラウザが起動してアプリケーションを表示


ここまでで開発の準備になります。ここから Angular CLI プロジェクトに実装を加えていきます。

機能実装

機能の実装は 1 ~ 15 のステップになります。

タスク数の表示

1.変数 taskText, taskCount を宣言する。

app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  //1
  taskText:string;
  taskCount: number;
}


2.インターポレーションでテンプレートに taskCount を表示する。

app.component.html
<div style="text-align:center">
  <h1>
      タスク数 = {{ taskCount }}<!-- 2 -->
  </h1>
</div>


3.FormsModule をインポートする。

app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';//3

import { AppComponent } from './app.component';


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule//3
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
}


タスクの追加機能

コンポーネントが初期化されるタイミングで発生するライフサイクルイベントをハンドルし、コンポーネントで利用する変数の初期化を行います。

4. OnInit をインポートする。
5. AppComponent に OnInit を実装する。
6. 変数 tasks を宣言する。
7. ngOnInit イベント内で taskText を空文字で、taskCount の値を tasks の要素数で初期化する。
8. addTask メソッドを追加する。

app.component.ts
import { Component, OnInit/*4*/ } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit/*5*/ {
  title = 'app';

  //1
  taskCount: number;
  tasks = [];//6
  
  ngOnInit(){
    //7
    this.taskText = "";
    this.taskCount = this.tasks.length;
  }

  //8
  addTask(taskNameValue: string){
    this.tasks.push(taskNameValue);
    this.taskCount = this.tasks.length;
  }
}

続いてテンプレート(HTML)側にも、データのバインドなどを実装していきます。


9. input(text) を実装し、taskName という名前をつける。
10. input(text) の value に ngModel を利用して taskText の値を双方向バインドする。
11. input(button) に click イベントを実装する。

app.component.html
<div style="text-align:center">
  <h1>
    タスク数 = {{ taskCount }}<!-- 2 -->
  </h1>

  <input #taskName type="text" [(ngModel)]="taskText"><!-- 9, 10 -->

  <input type="button" value="タスク追加" (click)="addTask(taskName.value)"><!-- 11 -->
</div>

ここまでで、input(button) をクリックすると、コンポーネント側で tasks 配列の要素が追加され、テンプレート側でバインドしている taskCount の値も増えていくことを確認することができます。

タスクのリスト表示

続けて、追加したタスクをリスト形式で表示するための実装を加えていきます。


12. tasks 配列の各要素をリスト表示する。

app.component.html
<div style="text-align:center">
  <h1>
    タスク数 = {{ taskCount }}<!-- 2 -->
  </h1>

  <input #taskName type="text" [(ngModel)]="taskText"><!-- 9, 10 -->

  <input type="button" value="タスク追加" (click)="addTask(taskName.value)"><!-- 11 -->
</div>

<ul>
  <!-- 12 -->
  <li *ngFor="let task of tasks">
    {{ task }}
  </li>
</ul>


13. タスクリストの位置調整

app.component.css
ul {
    position: relative;
    left: 40%;
}

ここまでで、ボタンクリックでタスクが追加していくようになります。

タスクの削除

タスクの追加ができたら、タスクの削除もできるようにします。タスクの削除は、タスク(li 要素)をクリックした時に行います。

14. input(button) に click イベントを登録する。

app.component.html
<div style="text-align:center">
  <h1>
    タスク数 = {{ taskCount }}<!-- 2 -->
  </h1>

  <input #taskName type="text" [(ngModel)]="taskText"><!-- 9, 10 -->

  <input type="button" value="タスク追加" (click)="addTask(taskName.value)"><!-- 11 -->
</div>

<ul>
  <!-- 12 -->
  <li *ngFor="let task of tasks; let idx = index;" (click)="removeTask(idx)"><!-- 14 -->
    {{ task }}
  </li>
</ul>

コンポーネント側で、タスクを削除するための removeTask イベントハンドラを実装します。

15. app.component.ts
//15
removeTask(idx:number){
  this.tasks.splice(idx, 1);
}

以上で、簡単ではありますが、Angular を利用した TO DO リストの作成ができました。


全ソースコード

各ファイルのソースコードは次のようになっています。

app.component.ts
import { Component, OnInit/*4*/ } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit/*5*/ {
  title = 'app';

  //1
  taskText:string;
  taskCount: number;

  tasks = [];//6
  
  ngOnInit(){
    //7
    this.taskText = "";
    this.taskCount = this.tasks.length;
  }

  //8
  addTask(taskNameValue: string){
    this.tasks.push(taskNameValue);
    this.taskCount = this.tasks.length;
    this.taskText = "";
  }
  //15
  removeTask(idx:number){
    this.tasks.splice(idx, 1);
  }
}

app.component.html
<div style="text-align:center">
  <h1>
    タスク数 = {{ taskCount }}<!-- 2 -->
  </h1>

  <input #taskName type="text" [(ngModel)]="taskText"><!-- 9, 10 -->

  <input type="button" value="タスク追加" (click)="addTask(taskName.value)"><!-- 11 -->
</div>

<ul>
  <!-- 12 -->
  <li *ngFor="let task of tasks; let idx = index;" (click)="removeTask(idx)"><!-- 14 -->
    {{ task }}
  </li>
</ul>

app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';//3

import { AppComponent } from './app.component';


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule//3
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.css
ul {
    position: relative;
    left: 40%;
}
以上になります。