2015-06-09 31 views
9

Der folgende Controller funktioniert ohne Probleme.JavaScript `bind` Methode funktioniert nicht wie erwartet

app.controller('foo', ['$scope',function ($scope) { 
     $scope.delete = function(){ 
      bar($scope); 
     } 
    }]); 

Ich habe versucht, es eine wenig sauberer zu machen von bind mit:

app.controller('foo', ['$scope',function ($scope) { 
     $scope.delete = bar.bind(null, $scope); 
    }]); 

Leider ist diese Form nicht so funktioniert erwartet und $scope ist immer mit einer alten Version von $ Umfang in gebundenem Verfahren geliefert (bar hier), auch nachdem $ scope geändert wurde, um auf einen anderen Wert zu verweisen. Was ist daran falsch?

Was noch?

Wenn ich hier nicht bind verwenden soll, was ist die Alternative?

+0

verwenden Was ist drin Util? Ich kann nicht darüber nachdenken, warum du das tun musst. –

+1

Scheint einen Missbrauch der Bindung an mich. –

+1

Ist das Problem, dass * $ scope.delete * ein Wert * ist, aber es ist ein * alter * Wert? Oder versagt die Funktion ganz oder gar nicht? – apsillers

Antwort

10

Ich gehe davon aus, dass Ihr Problem ist, dass Ihr gebundenes Util.bar ist immer mit einer alten Version von $scope geliefert, auch nach $scope geändert hat einen anderen Wert zu verweisen.

bind bindet Werte, keine Variablen. Sie binden den aktuellen Wert von $scope an Util.bar. Auf der anderen Seite erzwingt der erste Stil, dass der Bezeichner $scope bei jeder Ausführung der Funktion in einen Wert aufgelöst wird (oder wirklich in einen äußeren Variablen-Datensatz).

Wenn sich $scope ändert, um auf einen vollständig anderen Wert zu verweisen, müssen Sie das erste Formular verwenden. .bind(null, $scope) wird $scope sofort auf einen Wert auflösen und diesen Wert für immer verwenden, während das erste Formular ohne bei jeder Ausführung der Funktion $scope auflösen wird.

+0

Danke, Was ist die alternative Methode für die zweiten Codes. – PHPst

+0

@PHPst Die Alternative ist, was Sie bereits in Ihrem ersten Beispiel tun. Können Sie bearbeiten, um zu erklären, warum das nicht ausreicht? – apsillers

+0

als @apsillers sagte in 'bind' $ Bereich wird gelöst und wird in nachfolgenden Aufrufen verwendet sauberer Weg ist zuerst, aber immer noch wollen binden dann verwenden Sie diese app.controller ('foo', ['$ Scope', Funktion ($ Scope) { $ scope.delete = function() {bar.bind (null, $ scope);} }]); – vinayakj

2

Sind Sie sicher, dass bar nichts von Util verwendet? Tun Sie dies:

app.controller('foo', ['$scope',function ($scope) { 
    $scope.delete = Util.bar.bind(Util, $scope); 
}]); 
1

Wie in der Antwort von apsillers oben erwähnt, wird die bind-Methode sofort bei der Zuweisung ausgewertet - also wird der aktuelle Wert von $ scope als Argument an die Balkenfunktion übergeben. Was eine "sauberere" Alternative angeht, sehe ich nicht, warum Sie etwas "sauberer" brauchen: Sie wollen $ scope.delete als Funktion zuweisen, die bar mit dem aktuellen $ scope-Wert aufruft, was Ihr aktueller Code tut Wenn Sie zu einem T. noch sich für etwas ein wenig schlanker Code suchen weise könnte man immer ES6 Fett Pfeil Syntax nehmen (aber Sie würden eine Transpiler wie babel brauchen) - so würde der Code wie folgt aussehen:

app.controller('foo', ['$scope',function ($scope) { 
    $scope.delete =() => bar($scope); 
}]); 
4

Werfen Sie einen Blick auf diese Plunker.

$scope.delete1 = function(){ 
     bar($scope); 
    }; 

    $scope.delete2 = bar.bind(null, $scope); 

    $scope.delete3 = function(){ 
     bar(this); 
    }; 

Mir scheint es genau zu verhalten, wie es sein sollte: delete1 und delete2 scheinen die gleiche Sache auf Eltern und Kind-Controller zu tun. Löschen 3 verhält sich anders - der Grund wird in dieser Antwort sehr schön erklärt: controller's scope

Vielleicht können Sie genau angeben, welches Verhalten (Usecase) Sie falsch finden. Die Zurück-Links sind so, dass Sie die Controller-Seite verlassen und dann zu einer neuen Instanz des Controllers zurückkehren können (und einem neuen Bereich - wie Sie aus $ scope sehen können. $ Id).

-1

als @apsillers sagte, wird in bind $ Umfang aufgelöst und wird in nachfolgenden Aufrufen verwendet, so sauberer Weise die erste, aber immer noch ist, wenn Sie binden verwenden möchten dann

app.controller('foo', ['$scope',function ($scope) { 
    $scope.delete = function(){ 
     bar.bind(null, $scope); 
    } 
}]); 
+0

Wenn 'delete' aufgerufen wird, erstellt es nur einen Funktionswert, der weggeworfen wird. –

Verwandte Themen