$rootScope:inprog Tindakan sedang berlangsung

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...


person Matze    schedule 30.03.2016    source sumber


Jawaban (2)


Janji AngularJS sudah memanggil .apply() (di balik terpal) pada panggilan baliknya. Anda tidak dapat memanggil .apply lagi di dalam callback karena sudah .diterapkan, dan kesalahan "Sedang Berlangsung" menunjukkan hal itu. Hapus saja panggilan .apply dan itu akan berfungsi, kecuali Anda mengalami kesalahan lebih lanjut.

person Luis Masuelli    schedule 30.03.2016
comment
Oke; Saya tahu mengapa saya tidak melihat perubahan apa pun di UI... itu karena saya menggunakan alias c di luar cakupannya... bodohnya saya (-; Jawaban Anda benar; jika pengikatannya baik-baik saja, tidak ada perlu memanggil apply secara manual. - person Matze; 30.03.2016

mungkin Anda bisa mencoba this.model.data = data; lalu this.scope.apply();

person Alemndra    schedule 30.03.2016