Router UI Sudut: Memanggil fungsi pengontrol status anak

Saya telah bekerja dengan router ui sudut dan satu masalah terus muncul. Saya harap beberapa dari Anda dapat memberi saya saran bagaimana mengatasi masalah ini dengan cara yang bersih dan tidak diretas.

Pertimbangkan skenario berikut:

masukkan deskripsi gambar di sini

Di sebelah kiri saya memiliki navigasi samping dengan daftar kontak. Setelah saya mengklik kontak, detail kontak yang dipilih ditampilkan di status app.contacts.details. Segera setelah saya memilih kontak, beberapa kontrol muncul di header, misalnya. "edit" dan "hapus" (anggap saja sebagai contoh, pada kenyataannya tindakan ini lebih kompleks).

Idealnya, tombol-tombol ini hanya memanggil fungsi detailStateController, misalnya. detailStateController.delete() untuk menghapus kontak yang dipilih saat ini atau detailStateController.edit() untuk mengedit kontak yang dipilih (Anda mengerti idenya). Tentu saja ini tidak berhasil karena tombol edit dan hapus tidak berada dalam tampilan status app.contacts.details dan oleh karena itu detailStateController tidak berada dalam cakupannya.

Saya tahu ini bisa diselesaikan dengan menyiarkan acara, tapi saya ingin menghindari penggunaan acara jika memungkinkan.

Bagaimana Anda mengatasi ini?

Setiap saran sangat dihargai.


person omnibrain    schedule 31.05.2016    source sumber


Jawaban (3)


Pabrik bersifat tunggal dan dapat digunakan untuk berbagi data dan fungsi di seluruh pengontrol. Anda dapat menulisnya seperti ini:

app.factory("DataService", ["$http", function($http){
    var contacts = [];

    return {
        //sharing functions
        postItem: function(url, item) {
            return $http({
                url: url,
                method: 'POST',
                data: item
            });
        },
        putItem: function(url, item) {
            return $http({
                url: url,
                method: 'PUT',
                data: item
            });
        },
        deleteItem: function(url, item) {
            return $http({
                url: url,
                data: item,
                method: 'DELETE'
            });
        },
        setContacts = function(contacts) {
            contacts = contacts;
        },
        addContacts = function(contact) {
            contacts.push(contact);
        },
        deleteContact = function(contact) {
            var idx = this.contacts.indexOf(contact);
            contacts.splice(idx, 1);
        }
    };
}]);

Kemudian, di pengontrol Anda:

app.controller("ContactDetailsCtrl", ["$scope", "DataService", function($scope, DataService){
    $scope.deleteContact = function() {
        DataService.deleteItem('path/to/delete', { contactId: 123 }).then(function(response) {
            //remove from client-side array once it's removed form db
            DataService.deleteContact(contact);
        }).catch(function(response){
            //an error occurred
        });
    }
}]);
person Kyle    schedule 31.05.2016

Saya telah beralih dari gaya ini dan hanya menangani semuanya dari pengontrol dengan daftar. Jika Anda menghapus item dari pengontrol detail atau mengedit bidang yang ditampilkan di pengontrol induk, Anda tetap harus memperbarui pengontrol daftar. Ketika saya melakukannya seperti yang Anda lakukan sekarang, sepertinya saya harus melewati banyak rintangan tambahan yang disebabkan oleh detailnya ada di satu pengontrol dan daftarnya ada di pengontrol lain. Saya biasanya hanya memiliki properti daftar yang berupa array di pengontrol saya dan properti baris saat ini yang merupakan catatan lengkap yang ditampilkan. Lalu saya menggunakan ng-if untuk memeriksa baris saat ini dan menampilkannya dengan tepat. Ketika satu baris diklik, saya menggunakan $location.search untuk memperbarui url dan juga memeriksa $location search saat startup untuk tautan dalam. Hal ini menghasilkan satu pengontrol yang sedikit lebih besar, namun masih lebih kecil dari gabungan 2 pengontrol. Jika saya hanya menangani beberapa bidang, saya menyertakan semua bidang dalam daftar. Jika ada banyak data, saya melakukan panggilan layanan ketika item saat ini dalam daftar diubah untuk mendapatkan data untuk CurrentRow dan hanya memperbarui CurrentRow.

person Mike Feltman    schedule 31.05.2016

Saya pribadi suka membuat struktur berikut dalam kasus seperti itu.

Status router:

  • app.contacts.index - Untuk memuat toolbar untuk tampilan detail/daftar
  • app.contacts.list - Untuk daftar
  • app.contacts.detail - Untuk detailnya

Pengontrol (untuk setiap resp negara bagian):

function IndexCtrl($scope)
{
   $scope.contact = {}; // For containing the selected contact
   $scope.contacts = []; // List of contacts also on the parent view

   // Define Detail View functions here
   $scope.edit = Edit;
   $scope.delete = Delete;

   // Perform operations on $scope.contact/$scope.contacts
   function Edit() {}
   function Delete() {}
}

function DetailCtrl($scope)
{
    $scope.contact = $scope.$parent.contact = $scope.$parent.contacts[id]; // This way we work with the parent contact defined in IndexCtrl
}

function ListCtrl($scope, Contacts) 
{
    $scope.contacts = $scope.parent.contacts = Contacts.list(); // Contacts Service to retrieve the contact list
}
person Ankit Gupta    schedule 31.05.2016