質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
AngularJS

AngularJSはオープンソースのJavaScriptフレームワークです。ブラウザ上で動作するウェブアプリケーションの開発にMVCアーキテクチャを取り入れることを目的としています。

Q&A

解決済

1回答

2883閲覧

promise.thenのsuccessCallback内でのメソッドの使用方法について

akabee

総合スコア1947

AngularJS

AngularJSはオープンソースのJavaScriptフレームワークです。ブラウザ上で動作するウェブアプリケーションの開発にMVCアーキテクチャを取り入れることを目的としています。

0グッド

0クリップ

投稿2016/11/27 09:08

###前提・実現したいこと
promise.thenのsuccessCallback内でメソッド呼び出しをしているのですが、下記の通りのエラーとなります。これはなぜでしょうか?
this.a ではなく、宣言、呼び出しとも$scope.aとすると問題ありませんでしたが、これはどのような仕様によるものでしょうか。

個人的にあまり$scopeは利用したくないのですが、$scopeを利用せずにsuccessCallback内でメソッドの呼び出しをするにはどのようにすべきでしょうか。

###発生している問題・エラーメッセージ

TypeError:this.a is not a function

###該当のソースコード

AngularJS

1angular.module(app_Name) 2 3.controller('LoginController', function($http, LoginService) { 4 5 this.login = function() { 6 7 LoginService.login() 8 .then( 9 function(){ 10 this.a //ここがエラーとなる 11 12 }, 13 14 function(errorReason){ 15 16 } 17 18 }); 19 }; 20 21 this.a = function(){ 22 //処理 23 } 24 25}); 26

###試したこと
this.a ではなく、宣言、呼び出しとも$scope.aとすると問題ありませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

javascriptのthis

javascriptのthisはどこが呼び出しているかよりも、どいつが呼び出しているか
によって値が左右されるため、呼び出し方によっては期待した動作をしないことがあります。
※単純にコントローラー(どこが)に作成したメソッドが呼ばれるわけではありません

以下のサンプルですとwindowオブジェクトがthisになっています。
ですので単純にthisを使おうとすると呼び出し側の事を考えなければなら無い為
「var self = this;」等としてthisの値を別の変数に置き換えるとわかりやすいと思います。

補足

call,apply,bind,アロー関数等を使うとその限りではありません

動作サンプル

リンク

コード

html

1<html> 2 <head> 3 <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.min.js"></script> 4 <script> 5 6 // グローバルな呼び出し 7 window.a = function(){ 8 alert('windowオブジェクトのa()が呼び出されました') 9 } 10 11 // angularjsの定義 12 var app = angular.module('myApp', []); 13 14 // コントローラー 15 app.controller('LoginController', function($scope, LoginService) { 16 17 var self = this; 18 19 $scope.login = function(){ 20 LoginService.login().then(function(){ 21 22 if(this.a){ 23 this.a(); 24 }else{ 25 alert('this.a()が呼び出されませんでした'); 26 } 27 28 if(self.a){ 29 self.a(); 30 }else{ 31 alert('self.a()が呼び出されませんでした'); 32 } 33 34 if($scope.a){ 35 $scope.a(); 36 }else{ 37 alert('$scope.a()が呼び出されませんでした'); 38 } 39 }); 40 } 41 42 // thisの呼び出し 43 this.a = function(){ 44 alert('LoginController(this)のa()が呼び出されました'); 45 } 46 47 // selfの呼び出し 48 self.a = function(){ 49 alert('LoginController(self)のa()が呼び出されました'); 50 } 51 52 // $scopeの呼び出し 53 $scope.a = function(){ 54 alert('LoginController($scope)のa()が呼び出されました'); 55 } 56 57 }); 58 59 // サービス 60 app.factory('LoginService', function($q, $timeout){ 61 var self = {}; 62 63 // 非同期ログイン処理 64 self.login = function(){ 65 var d = $q.defer(); 66 $timeout(function() { 67 alert('ログイン完了!'); 68 d.resolve(); 69 }, 1000); 70 return d.promise; 71 } 72 73 // サービスのthis呼び出し 74 this.a = function(){ 75 alert('LoginService(this)のa()が呼び出されました'); 76 } 77 78 // サービスのself呼び出し 79 self.a = function(){ 80 alert('LoginService(self)のa()が呼び出されました'); 81 } 82 83 return self; 84 }); 85 </script> 86 </head> 87 <body> 88 <div ng-app="myApp"> 89 <div ng-controller="LoginController"> 90 <button ng-click="login()">ログイン</button> 91 </div> 92 </div> 93 </body> 94</html>

投稿2016/11/28 08:34

編集2016/11/28 08:37
pinpikokun

総合スコア376

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akabee

2016/11/29 00:44

回答ありがとうございます。 その後同様の内容には自分でもたどり着いていたのですが、難しいですね・・。精進します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問