Saya mulai bekerja dengan Angular Material
dan kesulitan memahami masalah dengan fungsionalitas $scope
.apply
... setiap kali saya mencoba memberi tahu UI tentang perubahan dengan menelepon apply
, gagal karena kesalahan. Saya tahu ada pertanyaan serupa tentang SO, tetapi dalam kasus saya data tidak disimpan oleh scope
tetapi oleh instance pengontrol...
Saya juga menggunakan TypeScript
untuk implementasi pengontrol saya; tidak yakin, tapi ini sepertinya jarang terjadi, karena sebagian besar kode contoh yang saya temukan didasarkan pada implementasi pengontrol inline tepat di tampilan.
Pengontrol saya terlihat seperti itu...
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;
}
}
Pengontrol menyediakan metode querySampleData
yang memperoleh beberapa data dari layanan jarak jauh (menggunakan IHttpService
untuk panggilan API asinkron). Pengontrol digunakan oleh tampilan dengan cara berikut...
<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>
Inisialisasi pengontrol berfungsi dengan baik; semua dependensi dimasukkan dengan benar ke dalam pengontrol dan pengikatan ke metode querySampleData
berfungsi seperti yang diharapkan (ketika saya mengklik tombol, metode tersebut dipanggil). Jika saya menetapkan data yang diterima ke model, UI tidak diperbarui, jadi saya menambahkan panggilan ke metode $apply
untuk memberi tahu UI tentang perubahan... yang memberi saya kesalahan yang saya sebutkan di atas.
Pembaruan:
Dokumentasinya ada di: https://docs.angularjs.org/error/$rootScope/inprog merekomendasikan untuk menggunakan $timeout
daripada $apply
untuk memastikan eksekusi asinkron; tentu saja ini memperbaiki kesalahannya, tetapi UI tidak berubah...