カテゴリー別アーカイブ: コーディング

AngularJSコードサンプル(カスタムディレクティブ v1.2.23)

AngularJS : 1.2.23
Bootstrap : 3.x
 
■目次
(1)基本的なカスタムディレクティブの作成方法
(2)子スコープ、隔離スコープの設定
(3)transcludeオプション、ng-transcludeディレクティブの使用例
(4)ディレクティブ内でコントローラを生成し、他のディレクティブで利用
(5)compile関数の使用例
 

(1)基本的なカスタムディレクティブの作成方法

1)カスタムディレクティブを使用しない場合

  1. {{item.product_name}} : {{item.price | number:0}}円

2)カスタムディレクティブを使用した場合


1)カスタムディレクティブを使用しない場合
<ol>
  <li ng-repeat='item in products'>
    {{item.product_name}} : {{item.price | number:0}}円
  </li>
</ol>
2)カスタムディレクティブを使用した場合
<div products-list="products"></div>

var demoApp = angular.module('demoApp', []);
demoApp.controller("cus1Ctrl", function($scope) {
  $scope.products = [
    {product_name: "デジタルカメラ",price: 8500},
    {product_name: "ノートパソコン",price: 39000},
    {product_name: "テレビ",price: 15900},
    {product_name: "ファンヒーター",price: 9800}
  ];
});

demoApp.directive("productsList", function () {
  return {
    link: function (scope, element, attrs) {
      scope.data = scope[attrs["productsList"]];
    },
    scope: true,
    template: "<ol><li ng-repeat='item in data'>{{item.product_name}} : {{item.price | number:0}}円</li></ol>",
    restrict: "A"
  }
});

(2)子スコープ、隔離スコープの設定

0)親スコープと共有:商品リスト(カメラ、テレビ、パソコン)

①親スコープ
フィルター(変数name)

②カスタムディレクティブA

③カスタムディレクティブB

1)子スコープ:商品リスト(カメラ、テレビ、パソコン)

①親スコープ
フィルター(変数name)

②カスタムディレクティブA

③カスタムディレクティブB

2)隔離スコープ(2Way):商品リスト(カメラ、テレビ、パソコン)

①親スコープ
変数parebind

②カスタムディレクティブA

③カスタムディレクティブB

3)隔離スコープ(1Way):商品リスト(カメラ、テレビ、パソコン)

①親スコープ
変数parebind

②カスタムディレクティブA

③カスタムディレクティブB

4)隔離スコープ(親スコープの関数を実行)

①親スコープ
会員非会員

②カスタムディレクティブA

③カスタムディレクティブB


0)親スコープと共有:商品リスト(カメラ、テレビ、パソコン)<br />
<p>
  <strong>①親スコープ</strong><br />
  <span>フィルター(変数name)<input ng-model=name /></span></br>
</p>
<strong>②カスタムディレクティブA</strong><br />
<div ordered-list0="products"></div>
<strong>③カスタムディレクティブB</strong><br />
<div ordered-list0="products"></div>
1)子スコープ:商品リスト(カメラ、テレビ、パソコン)<br />
<p>
  <strong>①親スコープ</strong><br />
  <span>フィルター(変数name)<input ng-model=name /></span></br>
</p>
<strong>②カスタムディレクティブA</strong><br />
<div ordered-list1="products"></div>
<strong>③カスタムディレクティブB</strong><br />
<div ordered-list1="products"></div>
2)隔離スコープ(2Way):商品リスト(カメラ、テレビ、パソコン)<br />
<p>
  <strong>①親スコープ</strong><br />
  <span>変数parebind<input ng-model="parebind" /></span></br>
</p>
<strong>②カスタムディレクティブA</strong><br />
<div ordered-list2 namescope="products" bindscope="parebind"></div>
<strong>③カスタムディレクティブB</strong><br />
<div ordered-list2 namescope="products" bindscope="parebind"></div>
3)隔離スコープ(1Way):商品リスト(カメラ、テレビ、パソコン)<br />
<p>
  <strong>①親スコープ</strong><br />
  <span>変数parebind<input ng-model="parebind" /></span></br>
</p>
<strong>②カスタムディレクティブA</strong><br />
<div ordered-list3 namescope={{products}} bindscope={{parebind}}></div>
<strong>③カスタムディレクティブB</strong><br />
<div ordered-list3 namescope={{products}} bindscope={{parebind}}></div>
4)隔離スコープ(親スコープの関数を実行)<br />
<p>
  <strong>①親スコープ</strong><br />
  <input type="radio" ng-model="group" value="member">会員<input type="radio" ng-model="group" value="">非会員<br/>
</p>
<strong>②カスタムディレクティブA</strong><br />
<div ordered-list4 namescope="products" bindscope="parebind" feescope="getFee(group)"></div>
<strong>③カスタムディレクティブB</strong><br />
<div ordered-list4 namescope="products" bindscope="parebind" feescope="getFee(group)"></div>

var demoApp = angular.module('demoApp', []);

demoApp.controller("scopeCtrl", function($scope) {
  $scope.products = [
    {product_name: "デジタルカメラA",price: 8500},
    {product_name: "ノートパソコンA",price: 39000},
    {product_name: "テレビA",price: 15900},
    {product_name: "デジタルカメラB",price: 9800},
    {product_name: "テレビB",price: 25900}
  ];
  $scope.name = "カメラ";
  $scope.parebind = "親スコープで設定した初期値";
  $scope.group = "member";
  $scope.getFee = function (grp) {
    return grp == "member" ? "送料は無料です。" : "送料は1商品1,000円です。";
  }
});

demoApp.directive("orderedList0", function () {
  return {
    link: function (scope, element, attrs) {
      scope.data = scope[attrs["orderedList1"]];
    },
    scope: false,
    template: "<p>フィルター(変数name): <input ng-model=name /></p><ol><li ng-repeat='item in data | filter: name'>{{item.product_name}} : {{item.price | number:0}}円</li></ol></p>",
    restrict: "A"
  }
});

demoApp.directive("orderedList1", function () {
  return {
    link: function (scope, element, attrs) {
      scope.data = scope[attrs["orderedList1"]];
    },
    scope: true,
    template: "<p>フィルター(変数name): <input ng-model=name /></p><ol><li ng-repeat='item in data | filter: name'>{{item.product_name}} : {{item.price | number:0}}円</li></ol></p>",
    restrict: "A"
  }
});

demoApp.directive("orderedList2", function () {
  return {
    scope: {
      localname: "=namescope",
      localbind: "=bindscope"
    },
    template: "<p>2Way(変数localbind): <input ng-model=localbind /><br />フィルター(変数key): <input ng-model=key /><ol><li ng-repeat='item in localname | filter: key'>{{item.product_name}} : {{item.price | number:0}}円</li></ol></p>",
    restrict: "A"
  }
});

demoApp.directive("orderedList3", function () {
  return {
    scope: {
      localname: "@namescope",
      localbind: "@bindscope"
    },
    template: "<p>1Way(変数localbind): <input ng-model=localbind /><br />データ(変数localname): {{localname}}</p>",
    restrict: "A"
  }
});

demoApp.directive("orderedList4", function () {
  return {
    scope: {
      localname: "=namescope",
      localbind: "=bindscope",
      localfee: "&feescope"
    },
    template: "<p><ol>  <li ng-repeat='item in localname | filter: key'>{{item.product_name}} : {{item.price | number:0}}円</li></ol><span>※{{localfee()}}<span></p>",
    restrict: "A"
  }
});

(3)transcludeオプション、ng-transcludeディレクティブの使用例


{{text}}


<input type="text" ng-model="title"><br/>
<textarea ng-model="text" rows="3"></textarea><br/>
<panel title="{{title}}">{{text}}</panel>

var demoApp = angular.module('demoApp', []);

demoApp.controller("transCtrl", function($scope) {
  $scope.title = 'パネルのタイトル';
  $scope.text = 'パネルの本文';
});

demoApp.directive("panel", function () {
  return {
    restrict: "E",
    scope: { title:'@' },
    template: '<div class="panel panel-default"><div class="panel-heading"><h4>{{title}}</h4></div><div class="panel-body"><p ng-transclude></p></div></div>',
    transclude: true,
  }
});

(4)ディレクティブ内でコントローラを生成し、他のディレクティブで利用

商品名 単価 個数
合計金額(税込): {{totalPrice | number:0}}円

<table class="table table-striped" product-total="totalPrice"
       product-data="products">
  <tr><th>商品名</th><th>単価</th><th>個数</th></tr>
  <tr ng-repeat="item in products" product-item></tr>
  <tr><th>合計金額(税込):</th><td colspan="2">{{totalPrice | number:0}}円</td></tr>
</table>

var demoApp = angular.module('demoApp', []);

demoApp.controller("ctlCtrl", function($scope) {
  $scope.products = [
    { name: "商品A", price: 100, quantity: 2 },
    { name: "商品B", price: 150, quantity: 3 },
    { name: "商品C", price: 200, quantity: 1 }
  ];
});

demoApp.directive("productItem", function () {
  return {
    template: "<td>{{item.name}}</td><td>{{item.price}}</td><td><input ng-model='item.quantity' /></td>",
    require: "^productTotal",
    link: function (scope, element, attrs, ctrl) {
      scope.$watch("item.quantity", function () {
        ctrl.updateTotal();
      });
    }
  }
});

demoApp.directive("productTotal", function () {
  return {
    scope: { total: "=productTotal", data: "=productData" },
    controller: function ($scope, $element, $attrs) {
      this.updateTotal = function() {
        var calc = 0;
        for (var i = 0; i < $scope.data.length; i++) {
          calc += $scope.data[i].quantity * $scope.data[i].price * 1.08;
        }
        $scope.total = calc;
      }
    }
  }
});

(5)compile関数の使用例

パネルタイトル

パネル本文。タイトルをクリックすると色が変ります。


<panel-repeat repeat="3">
  <div class="panel panel-default">
    <div class="panel-heading">
      <h2 class="panel-title">パネルタイトル</h3>
    </div>
    <div class="panel-body">
      パネル本文。タイトルをクリックすると色が変ります。
    </div>
  </div>
</panel-repeat>

var demoApp = angular.module('demoApp', []);

demoApp.directive("panelRepeat", function () {
  return {
    restrict: "E",
    compile: function(tElement, attrs) {
      var content = tElement.children();
      for (var i = 1; i < attrs.repeat; i++) {
        tElement.append(content.clone());
      };
      return function (scope, elem, attrs) {
        elem.on('click', function() {
          elem.find("h2").css({ "color": "red" }); 
        });
      };
    }
  };
});

関連記事の目次

AngularJSコードサンプル(sce、sanitize)

AngularJS : 1.6.5
Bootstrap : 3.3.7
 
※v1.2.3のサンプルはこちら
 

(1)$sce、$sanitizeサービスを使ってHTMLデータを表示

1)AngularJSの通常のバインド
{{htmlData}}

2)$sanitizeサービスとng-bind-htmlディレクティブを使用

3)$sceのtrustAsHtmlを使用


1)AngularJSの通常のバインド<br />
<span>{{htmlData}}</span><br />
2)$sanitizeサービスとng-bind-htmlディレクティブを使用<br />
<span ng-bind-html="htmlData"></span><br />
3)$sceのtrustAsHtmlを使用<br />
<span ng-bind-html="trustedData"></span><br />

var demoApp = angular.module('demoApp', ['ngSanitize']);

demoApp.controller("sceCtrl", function ($scope,$sce) {
  $scope.htmlData = "<b style='color: red;' onmouseover=alert('Alert!')>mouseover</b>";
  $scope.trustedData = $sce.trustAsHtml($scope.htmlData);
});

関連記事の目次

AngularJSコードサンプル(sce、sanitize v1.2.23)

AngularJS : 1.2.23
Bootstrap : 3.2.0

(1)$sce、$sanitizeサービスを使ってHTMLデータを表示

1)AngularJSの通常のバインド
{{htmlData}}

2)$sanitizeサービスとng-bind-htmlディレクティブを使用

3)$sceのtrustAsHtmlを使用


1)AngularJSの通常のバインド<br />
<span>{{htmlData}}</span><br />
2)$sanitizeサービスとng-bind-htmlディレクティブを使用<br />
<span ng-bind-html="htmlData"></span><br />
3)$sceのtrustAsHtmlを使用<br />
<span ng-bind-html="trustedData"></span><br />

var demoApp = angular.module('demoApp', ['ngSanitize']);

demoApp.controller("sceCtrl", function ($scope,$sce) {
  $scope.htmlData = "<b style='color: red;' onmouseover=alert('Alert!')>mouseover</b>";
  $scope.trustedData = $sce.trustAsHtml($scope.htmlData);
});

関連記事の目次

AngularJSのデータバインディングのディレクティブの概要

AngularJSのデータバインディングのディレクティブの概要についてまとめました。
 
デモとコードサンプルはこちら
 
※目次をクリックすると目次の下部にコンテンツが表示されます。

1Wayデータバインディング
・1Wayデータバインディングの設定をすると、スクリプト内のデータモデルに設定した変数の値がHTML内の関連付けられた要素に即座に反映される。
 
・1Wayデータバインディングを利用するには、二重波括弧{{…}}を使用するか、ng-bind、ng-bind-templateディレクティブを使用する。
 
・{{…}}の方が簡単に記述できるので、通常はこちらを使用する。
 ng-bindは一つのデータバインディングしか利用できないので、二つ以上ある場合はng-bind-templateディレクティブを使用する必要がある。
 
●使用例
 
下記のようにスクリプトで$scopeサービスを使って変数に値を設定すると、設定した値がHTMLの要素にバインディングされ、HTMLに値が表示される。
 
(スクリプト)
$scope.country = “日本”;
$scope.gender = “男性”;
 
(HTML)
私は{{country}}在住の{{gender}}です
<div>私は<span ng-bind=”country”></span>在住です。</div>
<div>ng-bind-template:私は{{country}}在住の{{gender}}です。</div>
 
※二重波括弧の文字を表示したい場合は?
 
AngularJSでは、二重波括弧は1Wayデータバインディングとして解釈されてしまうため、そのままでは文字として表示する事が出来ない。
 
表示する場合は、下記のようにng-non-bindableディレクティブを使う。
<div ng-non-bindable>二重波括弧{{…..}}を表示するには、ng-non-bindableを使用。</div>

2Wayデータバインディング
・1WayデータバインディングではスクリプトからHTMLの要素へ、という方向だが、2WayデータバインディングではHTMLの要素からスクリプトへ反映させ、双方向に同期させることも出来る。
 この場合は、ng-modelディレクティブを使用する。ユーザーがデータを入力できるHTML要素と一緒に使用する必要があるので、input、texterea、select要素などの属性に指定して使用する。
 
●使用例
 
下記例では、nameを2Wayデータバインディングとして設定してあるので、ユーザーが入力した値が即座に上の行の「私の名前は・・」の部分に表示される。
 
(スクリプト)
$scope.name = “初期値”;
 
(HTML)
<div>私の名前は{{name}}です。</div>
名前:<input ng-model=”name” />
 
デモとコードサンプルはこちら

関連記事の目次

AngularJSコードサンプル(http interceptor)

AngularJS : 1.6.5
Bootstrap : 3.3.7
 
※v1.2.3のサンプルはこちら
 

(1)$httpサービスのInterceptor



レスポンスデータ

名前 年齢 住所
{{item.id}} {{item.name}} {{item.age}} {{item.address}}

<button ng-click="getFriends(true)">データ取得</button><br />
<button ng-click="getFriends(false)">データ取得(エラー)</button><br />
<strong>レスポンスデータ</strong><br />
    <table class="table table-striped">
  <thead>
    <tr>
      <th>№</th><th>名前</th><th>年齢</th><th>住所</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="item in friends" >
      <td>{{item.id}}</td><td>{{item.name}}</td><td>{{item.age}}</td><td>{{item.address}}</td>
    </tr>
  </tbody>
</table>

1)アノニマスのファクトリを使ってinterceptorを設定する方法
var demoApp = angular.module('demoApp', []);
demoApp.config(function($httpProvider) {
  $httpProvider.interceptors.push(function ($q) {
    return {
      request: function(config) {
        config.headers.Authorization = 'Basic xxxx';
        console.log('Interceptor:request', config.headers);
        return config;
      },
      requestError: function(rejection) {
        console.log('Interceptor:requestError', rejection);
        return $q.reject(rejection);
      },
      response: function(response) {
        console.log('Interceptor:response', response);
        return response;
      },
      responseError: function(rejection) {
        console.log('Interceptor:responseError', rejection.statusText);
        return $q.reject(rejection);
      }
    }
  })
});

demoApp.controller('intceptCtrl', function ($scope, $http) {
  $scope.getFriends = function (tf) {
    var svrURL = (tf ? "friends.json" :"invalid-url.php");
    var config = {};
    $http.get(svrURL, config)
      .then(function onSuccess(response) {
        console.log('Client:response', response.status);
        $scope.friends = response.data;
      }, function onError(response) {
        console.log('Client:responseError',response.status);
        $scope.friends = [];
      });
  };
});

2)サービスとしてinterceptorを登録する方法
var demoApp = angular.module('demoApp', []);
demoApp.factory('myInterceptor', function($q) {
  return {
    request: function(config) {
      config.headers.Authorization = 'Basic xxxx';
      console.log('Interceptor:request', config.headers);
      return config;
    },
    requestError: function(rejection) {
      console.log('Interceptor:requestError', rejection);
      return $q.reject(rejection);
    },
    response: function(response) {
      console.log('Interceptor:response', response);
      return response;
    },
    responseError: function(rejection) {
      console.log('Interceptor:responseError', rejection.statusText);
      return $q.reject(rejection);
    }
  };
});
demoyApp.config(function($httpProvider) {
  $httpProvider.interceptors.push('myInterceptor');
});

関連記事の目次

AngularJSコードサンプル(http interceptor v1.2.23)

AngularJS : 1.2.23
Bootstrap : 3.2.0

(1)$httpサービスのInterceptor



レスポンスデータ

名前 年齢 住所
{{item.id}} {{item.name}} {{item.age}} {{item.address}}

<button ng-click="getFriends(true)">データ取得</button><br />
<button ng-click="getFriends(false)">データ取得(エラー)</button><br />
<strong>レスポンスデータ</strong><br />
    <table class="table table-striped">
  <thead>
    <tr>
      <th>№</th><th>名前</th><th>年齢</th><th>住所</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="item in friends" >
      <td>{{item.id}}</td><td>{{item.name}}</td><td>{{item.age}}</td><td>{{item.address}}</td>
    </tr>
  </tbody>
</table>

1)アノニマスのファクトリを使ってinterceptorを設定する方法
var demoApp = angular.module('demoApp', []);
demoApp.config(function($httpProvider) {
  $httpProvider.interceptors.push(function ($q) {
    return {
      request: function(config) {
        config.headers.Authorization = 'Basic xxxx';
        console.log('Interceptor:request', config.headers);
        return config;
      },
      requestError: function(rejection) {
        console.log('Interceptor:requestError', rejection);
        return $q.reject(rejection);
      },
      response: function(response) {
        console.log('Interceptor:response', response);
        return response;
      },
      responseError: function(rejection) {
        console.log('Interceptor:responseError', rejection.statusText);
        return $q.reject(rejection);
      }
    }
  })
});

demoApp.controller('intceptCtrl', function ($scope, $http) {
  $scope.getFriends = function (tf) {
    var svrURL = (tf ? "friends.json" :"invalid-url.php");
    var config = {};
    $http.get(svrURL, config)
      .success(function (data, status, headers, config) {
        console.log('Client:response', status);
        $scope.friends = data;
      })
      .error(function (data, status, headers, config) {
        console.log('Client:responseError',status);
        $scope.friends = [];
      });
  };
});

2)サービスとしてinterceptorを登録する方法
var demoApp = angular.module('demoApp', []);
demoApp.factory('myInterceptor', function($q) {
  return {
    request: function(config) {
      config.headers.Authorization = 'Basic xxxx';
      console.log('Interceptor:request', config.headers);
      return config;
    },
    requestError: function(rejection) {
      console.log('Interceptor:requestError', rejection);
      return $q.reject(rejection);
    },
    response: function(response) {
      console.log('Interceptor:response', response);
      return response;
    },
    responseError: function(rejection) {
      console.log('Interceptor:responseError', rejection.statusText);
      return $q.reject(rejection);
    }
  };
});
demoyApp.config(function($httpProvider) {
  $httpProvider.interceptors.push('myInterceptor');
});

関連記事の目次