0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AngularJSで関数を動かして分かったこと

Last updated at Posted at 2020-06-12

AngularJSを使っていて気になったことメモ

関数の書き方はいくつかある。

methodTest.js
let app = angular.module('methodTest', []);

app.controller('meController', function($scope) {

  // その1 普通に定義
  let callA = function() {
    console.log('a');
  }

  // その2 依存サービス(?)に定義
  $scope.callB = function() {
    console.log('b');
  }
  
  // その3 Controllerに定義?  
  this.callC = function() {
    console.log('c');
  }
})

書き方によって呼び出せたり呼び出せなかったりするので色々確認。

関数を画面から呼ぶ

methodTest.html
<!doctype html>
<html ng-app="methodTest">
<head>
<title>Angularテスト</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
<script src="./methodTest.js"></script>
</head>
<body>
<div ng-controller="meController as meCtrl">
	<!-- ボタン押下でそれぞれのメソッド呼出 -->
	<button ng-click="callA()">callA</button>
	<button ng-click="callB()">callB</button>
	<button ng-click="callC()">callC</button>
</div>
</body>
</html>

buttons.png

A、B、Cを順に押した出力結果

b

callA、callCが呼び出せない。(Console上でエラーは出力されない)

Controllerを指定してみる。

methodTest.html

<div ng-controller="meController as meCtrl">
	<!-- meCtrl.をつける -->
	<button ng-click="meCtrl.callA()">callA</button>
	<button ng-click="meCtrl.callB()">callB</button>
	<button ng-click="meCtrl.callC()">callC</button>
</div>

A、B、Cを順に押した出力結果

c

callCが呼べるように。
callA、callBは呼び出せない。(Console上でエラーは出力されない)

callA式もHTMLから呼び出せないか模索
onClickにしてみる。確認用にcallDボタンも増やす。

methodTest.html

<div ng-controller="meController as meCtrl">
	<!-- onClickにしてみる -->
	<button onClick="callA()">callA</button>
	<button ng-click="callB()">callB</button>
	<button ng-click="meCtrl.callC()">callC</button>
	<button onClick="callD()">callD</button>
</div>

methodTest.js
app.controller('meController', function($scope) {
  // その1 普通に定義
  let callA = function() {
    console.log('a');
  }

  // その2 依存サービス(?)に定義
  $scope.callB = function() {
    console.log('b');
  }
  
  // その3 Controllerに定義?  
  this.callC = function() {
    console.log('c');
  }
})

// その4 Controllerの外に出す(もはやAngularJSではない)
let callD = function() {
	console.log('d');
}

buttons2.png

A、B、C、Dを順に押した出力結果

Uncaught ReferenceError: callA is not defined
    at HTMLButtonElement.onclick (methodTest.html:10)
b
c
d

callAは参照できない。無理そう。

まとめ

methodTest.js
app.controller('meController', function($scope) {
  // 画面からは呼べない
  let callA = function() {
    console.log('a');
  }

  // callB()で画面から呼べる
  $scope.callB = function() {
    console.log('b');
  }
  
  // [コントローラー].callC()で画面から呼べる
  this.callC = function() {
    console.log('c');
  }
})

// 画面から呼べる
let callD = function() {
	console.log('d');
}

関数を関数の中から呼ぶ

コードを少し修正。callAは$scope.callAViaを経由して呼ぶ。

methodTest.html
<div ng-controller="meController as meCtrl">
	<button ng-click="callAVia()">callA</button>
	<button ng-click="callB()">callB</button>
	<button ng-click="meCtrl.callC()">callC</button>
</div>

methodTest.js
app.controller('meController', function($scope) {
  // その1 普通に定義
  let callA = function() {
    console.log('a');
  }
  
  // その1を呼び出す用
  $scope.callAVia = function() {
    callA();
  }

  // その2 依存サービス(?)に定義
  $scope.callB = function() {
    console.log('b');
  }
  
  // その3 Controllerに定義?  
  this.callC = function() {
    console.log('c');
  }
})

buttons.png

A、B、Cを順に押した出力結果

a
b
c

letで定義した関数から呼ぶ

  let callA = function() {
    console.log('a');
    $scope.callB();
    this.callC();
  }

callA関数の中から$scope.callBとthis.callCを呼び出す。

callAボタンを押した出力結果

a
b
TypeError: this.callC is not a function

callCは呼び出せない。
this.callC is not a functionで関数じゃないと言われているのでthis.callC;としたところエラー無しで何も出力されなくなる。
試しに以下の書き方でもエラーとなる。

$scope.callC();
callC();

(2020/6/17追記)
callAをアロー関数にすると呼び出しに成功

  let callA = () => {
    console.log('a');
    $scope.callB();
    this.callC();
  }

出力結果

a
b
c

依存サービス($scope)に定義した関数から呼ぶ

methodTest.js
  let callA = function() {
    console.log('a');
  }

  $scope.callB = function() {
    console.log('b');
    callA();
    this.callC();
  }

callBボタンを押した出力結果

a
b
TypeError: this.callC is not a function

以下の書き方でもエラーとなる。

$scope.callC();
callC();

(2020/6/17追記)
callBをアロー関数にすると呼び出しに成功

  $scope.callB = () => {
    console.log('b');
    callA();
    this.callC();
  }

出力結果

b
a
c

Controllerに定義?した関数から呼ぶ

methodTest.js
  let callA = function() {
    console.log('a');
  }
  
  $scope.callB = function() {
    console.log('b');
  }
  
  this.callC = function() {
    console.log('c');
    callA();
    $scope.callB();
  }

callCボタンを押した出力結果

c
a
b

全て呼び出せる。

まとめ

app.controller('meController', function($scope) {
  // 「$scope.」からも「this.」からも呼び出せる
  let callA = function() {
    console.log('a');
  }
  
  // 「let」からも「this.」からも呼び出せる
  $scope.callB = function() {
    console.log('b');
  }
  
  // 「let」からも「$scope.」からも呼び出せない
  // 「let」、「$scope.」をアロー関数にすると呼び出せる
  this.callC = function() {
    console.log('c');
  }
})

総まとめ

→から↓を呼び出す表でまとめ。

html let $scope this let(アロー関数) $scope(アロー関数)
let × - -
$scope - -
this × ×

let同士、$scope同士、this同士の呼び出しも確認したところ問題なく呼べる。
思ったより挙動の違いがあって驚いた。何故。
AngularJSマスターにとっては当たり前体操なのかもしれない...自分はよく分かっていなかったので整理
コメントから、AngularJSの仕様とかではないらしい。普通にJavaScriptの勉強になりました。
なるほどなぁ

アロー関数と同様にthisを一度変数に入れてもcallCを呼び出せました。

参考

追記、修正

2020/6/17
Angular、Angular.js → AngularJSに修正
アロー関数について追記

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?