Ich begann mit Angular Material
zu arbeiten und habe Schwierigkeiten, ein Problem mit der $scope
zu verstehen. apply
Funktionalität ... immer wenn ich versuche, die UI über Änderungen zu benachrichtigen, indem Sie apply
aufrufen, schlägt es mit einem Fehler fehl. Ich weiß, dass es ähnliche Fragen zu SO gibt, aber in meinem Fall werden die Daten nicht von der scope
, sondern von der Controller-Instanz gespeichert ...
Ich verwende auch TypeScript
für meine Controller-Implementierung; nicht sicher, aber das scheint ziemlich ungewöhnlich zu sein, da der meiste Beispielcode, den ich gefunden habe, auf einer Inline-Controller-Implementierung in der Ansicht basiert.
Mein Controller so aussieht ...
module MyApp {
export class MyController {
private scope: angular.IScope;
private http: angular.IHttpService;
public model: { data: SampleData } = { data: { } };
constructor($scope: angular.IScope, $http: angular.IHttpService) {
this.scope = $scope;
this.http = $http;
}
public querySampleData(): void {
const serviceEndpoint: string = "http://localhost:8080/api/";
var promise: ng.IHttpPromise<SampleData> = this.http.get(serviceEndpoint + "sample", { });
var callback: ng.IHttpPromiseCallback<SampleData> = (
data: SampleData,
status: number,
headers: angular.IHttpHeaderGetter,
config: angular.IRequestConfig) => {
this.scope.apply(() => {
this.model.data = data;
};
};
promise.success(callback);
}
}
export interface SampleData {
message? string;
}
}
Der Controller bietet die querySampleData
Methode, die einige Daten von einem Remote-Service erhält (es verwendet IHttpService
für asynchrone API-Aufrufe). Die Steuerung wird von der Ansicht folgendermaßen verwendet:
<html ng-app="app">
<body ng-controller="MyController as c">
<div>
<button ng-click="c.querySampleData()"
aria-label="Query sample data">Query sample data</button>
<p>{{c.model.data.message}}</p>
</div>
...
<script src="../scripts/app.js"></script>
<script type="text/javascript">
var app = angular.module("app", ["ngMaterial"]);
app.controller("MyController", [ "$scope", "$http", MyApp.MyController ]);
</script>
</body>
</html>
Die Initialisierung des Controllers funktioniert einwandfrei; Alle Abhängigkeiten werden ordnungsgemäß in den Controller injiziert und auch die Bindung an die querySampleData
Methode funktioniert wie erwartet (wenn ich auf die Schaltfläche klicke, wird die Methode aufgerufen). Wenn ich die empfangenen Daten dem Modell zuweise, wird die Benutzeroberfläche nicht aktualisiert. Daher habe ich der Methode $apply
einen Anruf hinzugefügt, um die Benutzeroberfläche über Änderungen zu informieren, was mir den oben erwähnten Fehler gibt.
Update:
Die vorliegende Dokumentation: https://docs.angularjs.org/error/$rootScope/inprog empfiehlt $timeout
statt $apply
zu verwenden asynchrone Ausführung zu gewährleisten; natürlich korrigiert diese Fehler den Fehler, aber die Benutzeroberfläche nicht ändern ...
Okay; Ich habe herausgefunden, warum ich keine Änderungen in der UI gesehen habe ... es war, weil ich den Alias 'c' aus seinem Gültigkeitsbereich genommen habe ... blöd mich (-; Ihre Antwort ist richtig; wenn die Bindung in Ordnung ist ... Es ist nicht nötig, 'apply' manuell aufzurufen. – Matze