2016-08-16 5 views
5

に関連フィドルを.thenに渡すことです。いくつかのシナリオをテストするために、私はにメッセージをプッシュする範囲で配列を作成しました:

function returnAPromise(valToReturn){ 
    return $q(function(resolve, reject){ 
     $timeout(function(){ 
      resolve(valToReturn); 
     }, 500); 
    }); 
} 

は、私は、持っている:私はそう$のQ関数を返す関数を設定している

$scope.messages = []; 

このように見える結果に.then()コール:私は約束を配列にして解決されたことを値をプッシュしたいので

returnAPromise('third').then($scope.messages.push); 

は、私はちょうど会ったプッシュに渡すことができます考え出し

VM289 angular.js:12520 TypeError: Array.prototype.push called on null or undefined 
    at processQueue (VM289 angular.js:14792) 
    at VM289 angular.js:14808 
    at Scope.$eval (VM289 angular.js:16052) 
    at Scope.$digest (VM289 angular.js:15870) 
    at Scope.$apply (VM289 angular.js:16160) 
    at VM289 angular.js:17927 
    at completeOutstandingRequest (VM289 angular.js:5552) 
    at VM289 angular.js:5829 

私は機能にプッシュを囲む場合は、それが正常に動作します:

returnAPromise('third').then(function(message){ 
    $scope.messages.push(message) 
}); 

が、これは閉鎖問題であり、私は次のエラーを取得する、というメッセージ配列のHODが、ときに私がやります理解していないのですか?

答えて

6

それはthis

returnAPromise('third').then($scope.messages.push.bind($scope.messages)); 
+1

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind実施例のセクションには、問題を説明し、なぜ.bind()、それを解決します。残念ながら、これには、「新しいJavaScriptプログラマーにとってよくある間違い」という行が含まれています。 = [私は降格されました。 – sonicblis

1

を使用していますので、あなたが例

は一例で始めることができます私は受け入れ答えがあると知っているが、私はここで、より明確に

これを説明しますプッシュをバインドする必要があります

var scope = { 
    scopeFn: function() { 
    console.log('this', this) 
    } 
} 

function callFn(fn) { 
    fn(); 
} 

callFn(obj.scopeFn) // will log window object 
callFn(function() { 
    obj.scopeFn(); 
});// will log scope object 

ご覧のとおり、イオンは呼び出されたオブジェクトにこの値を与えますが、ラップせずに直接呼び出すとウィンドウオブジェクトが呼び出されます。

なぜですか?

thisは、呼び出されたオブジェクトにバインドされます。

最初の例では、callFn(obj.scopeFn)はファンクションをパラメータとして渡しているため、ファンクションがコールされると、scopeオブジェクトから直接呼び出されます。 (scopeオブジェクトが失われ、関数参照のみが送信されます)。

2番目の例では、オブジェクトから関数scopeFnを呼び出すため、thisはそのオブジェクトにバインドされます。あなたが解決のためのパラメータとして、あなたが渡している機能をバインドする必要があるので、それは常に意志この問題を解決するために

ソリューション

を(その呼び出されたときに全体のことがあるようscopeオブジェクトは、失われません)親オブジェクトから呼び出されたかのように呼び出されます。

var scopeMessage = $scope.messages; 
returnAPromise('third').then(scopeMessage.push.bind(scopeMessage)); 
関連する問題