Beberapa pengontrol dengan AngularJS dalam aplikasi satu halaman

102

Saya ingin tahu adalah bagaimana menggunakan beberapa pengontrol untuk aplikasi satu halaman. Saya telah mencoba mengetahuinya dan saya telah menemukan pertanyaan yang sangat mirip dengan pertanyaan saya, tetapi hanya ada satu ton jawaban berbeda yang memecahkan masalah tertentu di mana Anda akhirnya tidak menggunakan banyak pengontrol untuk satu aplikasi halaman.

Apakah karena tidak bijaksana menggunakan banyak pengontrol untuk satu halaman? Atau itu tidak mungkin?

Katakanlah saya sudah memiliki pengontrol carousel gambar kick-ass yang bekerja di halaman utama, tetapi kemudian saya belajar bagaimana (katakanlah) menggunakan modal dan saya membutuhkan pengontrol baru untuk itu juga (atau hal lain yang saya perlukan pengontrol). Apa yang akan saya lakukan?

Saya telah melihat beberapa jawaban untuk pertanyaan lain di mana mereka menanyakan hal yang hampir sama dengan saya dan orang-orang menjawab "* OMG. Mengapa Anda melakukan itu, lakukan saja ...".

Apa cara terbaik, atau bagaimana Anda melakukannya?

Edit

Banyak dari Anda yang menjawab untuk hanya mendeklarasikan dua pengontrol dan kemudian menggunakan ng-controller untuk memanggilnya. Saya menggunakan sedikit kode di bawah ini dan kemudian memanggil MainCtrl dengan ng-controller.

app.config(function($routeProvider, $locationProvider) {                        
  $routeProvider                                                                
       .when('/', {                                            
         templateUrl: "templates/main.html",                                               
         controller:'MainCtrl',                                
        })                                                                      
        .otherwise({                      
            template: 'does not exists'   
        });      
});

Mengapa saya bahkan perlu menyetel pengontrol di sini jika saya bisa menggunakan ng-controller tanpa itu? Inilah yang membuatku bingung. (dan Anda tidak dapat menambahkan dua pengontrol dengan cara ini, saya pikir ...)

TarkaDaal
sumber
Saya rasa saya tidak dapat mendeklarasikan 2 pengontrol untuk satu file .html? bagaimana itu dilakukan? when: /home, controller: MainCtrl. tidak dapat menambahkan lebih dari itu, atau apakah Anda bermaksud menyebutnya dengan ng-controller?
3
@Mosho, Anda langkah 1, langkah 2, selesai, tetapi jangan jelaskan bagaimana atau mengapa. Jika sesederhana itu, tolong jelaskan caranya. Itu seperti mengatakan gunakan AngularJS, Selesai. dapatkah Anda menjelaskan / menjelaskan? Atau karena dari bulan Juni, mereka mungkin tidak menjawab, dapatkah orang lain menjelaskan?
redfox05

Jawaban:

96

Apa masalahnya? Untuk menggunakan banyak pengontrol, cukup gunakan beberapa direktif ngController:

<div class="widget" ng-controller="widgetController">
    <p>Stuff here</p>
</div>

<div class="menu" ng-controller="menuController">
    <p>Other stuff here</p>
</div>

Anda harus memiliki pengontrol yang tersedia di modul aplikasi Anda, seperti biasa.

Cara paling dasar untuk melakukannya bisa sesederhana mendeklarasikan fungsi pengontrol seperti ini:

function widgetController($scope) {
   // stuff here
}

function menuController($scope) {
   // stuff here
}
J. Bruni
sumber
2
Apakah ini cara melakukannya? Saya menggunakan ituwhen /home, controller: MainCtrl
8
Jika Anda mendapatkan contoh yang menempatkan "ng-app" di setiap DIV di samping "ng-controller", coba pindahkan hanya satu "ng-app" ke dalam tag "body" (dan hapus per-div " ng-app ") jika hanya pengontrol pertama Anda yang berfungsi. (Saya ingat ini dari hari-hari pemula saya Angular.)
ftexperts
1
Satu-satunya masalah yang saya alami dengan menggunakan ng-controllerbeberapa elemen DOM, dikatakan dalam skenario di mana saya memiliki BANYAK item yang dicetak ke DOM melalui ng-repeat. Misalkan masing-masing melakukan panggilan ke ng-controller="myController. Dari beberapa log konsol yang saya lihat di aplikasi saya, myControllerdiinisialisasi ulang dengan SETIAP elemen yang dirender di DOM yang memanggilnya .... Mungkin saya mengacaukan sesuatu dalam penggunaan khusus saya, atau mungkin di luar cakupan OP pertanyaan, tetapi penasaran apakah orang lain pernah mengalaminya sama sekali ....
twknab
91

Saya pikir Anda kehilangan arti "aplikasi satu halaman".

Itu tidak berarti Anda secara fisik akan memiliki satu .html, sebaliknya Anda akan memiliki satu index.htmlfile .html utama dan beberapa NESTED. Jadi mengapa aplikasi satu halaman? Karena dengan cara ini Anda tidak memuat halaman dengan cara standar (yaitu panggilan browser yang menyegarkan halaman penuh) tetapi Anda hanya memuat bagian konten menggunakan Angular / Ajax. Karena Anda tidak melihat kedipan di antara perubahan halaman, Anda mendapat kesan bahwa Anda tidak berpindah dari halaman. Dengan demikian, Anda merasa seperti tinggal di satu halaman.

Sekarang, saya berasumsi bahwa Anda ingin memiliki konten GANDA untuk aplikasi SINGLE PAGE Anda: (misalnya) rumah, kontak, portofolio, dan toko. Aplikasi satu halaman / beberapa konten Anda (cara bersudut) akan diatur seperti ini:

  • index.html: berisi header, <ng-view>dan footer
  • contacts.html: berisi formulir kontak (tanpa header, tanpa footer)
  • portfolio.html: berisi data portofolio (tanpa header tanpa footer)
  • store.html: berisi penyimpanan, tidak ada header tanpa footer.

Anda berada di indeks, Anda mengklik menu yang disebut "kontak" dan apa yang terjadi? Angular menggantikan <ng-view>tag dengan contacts.htmlkode

Bagaimana Anda mencapai itu? dengan ngRoute, saat Anda melakukannya, Anda akan memiliki sesuatu seperti:

app.config(function($routeProvider, $locationProvider) {                        
  $routeProvider                                                                
       .when('/', {                                            
         templateUrl: "templates/index.html",                                               
         controller:'MainCtrl',                                
        })
        .when('/contacts', {                                            
         templateUrl: "templates/contacts.html",                                               
         controller:'ContactsCtrl',                                
        })                                                                 
        .otherwise({                      
            template: 'does not exists'   
        });      
});

Ini akan memanggil html yang tepat meneruskan pengontrol yang tepat untuk itu (harap dicatat: jangan tentukan ng-controllerdirektif contacts.htmljika Anda menggunakan rute )

Kemudian, tentu saja, Anda dapat mendeklarasikan sebanyak mungkin arahan ng-controller di dalam halaman contacts.html Anda. Mereka akan menjadi pengendali anak ContactCtrl(jadi mewarisi darinya). Tetapi untuk satu rute, di dalam routeProvider, Anda dapat mendeklarasikan satu Kontroler yang akan bertindak sebagai "Pengontrol Ayah dari tampilan parsial".

EDIT Bayangkan template / contacts.html berikut

<div>
    <h3>Contacts</h3>
    <p>This is contacts page...</p>
</div>

di atas routeProviderakan menyuntikkan pengontrol ke div berisi Anda. Pada dasarnya html diatas otomatis menjadi:

<div ng-controller="ContactsCtrl">
    <h3>Contacts</h3>
    <p>This is contacts page...</p>
</div>

Ketika saya mengatakan Anda dapat memiliki pengontrol lain, berarti Anda dapat menyambungkan pengontrol ke elemen DOM bagian dalam, sebagai berikut:

<div>
    <h3>Contacts</h3>
    <p ng-controller="anotherCtrl">Hello {{name}}! This is contacts page...     
    </p>
</div>

Saya harap ini sedikit memperjelas.

SEBUAH

Adhara
sumber
Jadi, jika Anda mendeklarasikan eg <div ng-controller="FancyStuffController">di dalam tag body yang telah diterapkan pengontrol, misalnya <body ng-controller="BodyController">, apakah ini akan berfungsi? im mendapatkan kesalahan tentang $apply already in progressketika saya melakukan ini, tetapi saya pikir itu terkait dengan dpd.js. Bukan untuk membahasnya, saya pikir itu hanya memuatnya dua kali atau sesuatu, tidak yakin bagaimana caranya, tetapi penggunaan pengontrol saya mungkin mencoba memuat ulang itu.
blamb
1
@BrianThomas Tentu, itu seharusnya berhasil. Hati-hati: jika Anda ingin memasukkan pengontrol dalam tampilan, gunakan $ routeProvider, jangan menulis ng-controller pada tag div.
Adhara
9

Saat ini saya sedang dalam proses membangun aplikasi satu halaman. Inilah yang saya miliki sejauh ini yang saya yakini akan menjawab pertanyaan Anda. Saya memiliki template dasar (base.html) yang memiliki div dengan ng-viewdirektif di dalamnya. Arahan ini memberitahu angular di mana harus memasukkan konten baru. Perhatikan bahwa saya sendiri baru mengenal angularjs jadi saya tidak bermaksud mengatakan ini adalah cara terbaik untuk melakukannya.

app = angular.module('myApp', []);                                                                             

app.config(function($routeProvider, $locationProvider) {                        
  $routeProvider                                                                
       .when('/home/', {                                            
         templateUrl: "templates/home.html",                                               
         controller:'homeController',                                
        })                                                                      
        .when('/about/', {                                       
            templateUrl: "templates/about.html",     
            controller: 'aboutController',  
        }) 
        .otherwise({                      
            template: 'does not exists'   
        });      
});

app.controller('homeController', [              
    '$scope',                              
    function homeController($scope,) {        
        $scope.message = 'HOME PAGE';                  
    }                                                
]);                                                  

app.controller('aboutController', [                  
    '$scope',                               
    function aboutController($scope) {        
        $scope.about = 'WE LOVE CODE';                       
    }                                                
]); 

base.html

<html>
<body>

    <div id="sideMenu">
        <!-- MENU CONTENT -->
    </div>

    <div id="content" ng-view="">
        <!-- Angular view would show here -->
    </div>

<body>
</html>
Austin
sumber
memang, saya juga menggunakan ng-view sehingga saya bisa menggunakan main.html di index.html saya. tetapi Anda memiliki / home dan / about dan dua pengontrol untuk masing-masing. Saya hanya memiliki index.html dengan ng-view ke main.html saya. Saya dapat mengatur dua pengontrol untuk main.html seperti yang telah Anda lakukan denganwhen /home
Lihatlah jawaban pertama dari posting ini: stackoverflow.com/questions/17354568/…
Austin
baik, saya tahu bagaimana mengatur lebih banyak when. Saya ingin dua pengontrol untuk satu template. Atau mungkin saya salah paham tentang apa yang ingin Anda sampaikan kepada saya?
Alih-alih menggunakan pengontrol, coba gunakan arahan. Anda dapat menggunakan banyak arahan pada satu template. Jika Anda masih ingin menggunakan pengontrol Anda, berikut adalah video tentang bagaimana arahan dapat dihubungkan dengan pengontrol: egghead.io/lessons/angularjs-directives-talking-to-controllers
Austin
6
<div class="widget" ng-controller="widgetController">
    <p>Stuff here</p>
</div>

<div class="menu" ng-controller="menuController">
    <p>Other stuff here</p>
</div>
///////////////// OR ////////////


  <div class="widget" ng-controller="widgetController">
    <p>Stuff here</p>
    <div class="menu" ng-controller="menuController">
        <p>Other stuff here</p>
    </div>
</div>

menuController memiliki akses untuk menu div. Dan widgetController memiliki akses ke keduanya.

Muhammad Awais
sumber
Ini tampaknya mudah, tetapi tidak memiliki suara positif. Apakah ini praktik terbaik atau buruk?
redfox05
1
apa yang akan Anda lakukan, jika Anda memiliki banyak halaman 100+ pengontrol! ... praktik yang ambigu.
ArifMustafa
3

Kita cukup mendeklarasikan lebih dari satu Controller dalam modul yang sama. Berikut contohnya:

  <!DOCTYPE html>
    <html>

    <head>
       <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js">
       </script>
      <title> New Page </title>


    </head> 
    <body ng-app="mainApp"> <!-- if we remove ng-app the add book button [show/hide] will has no effect --> 
      <h2> Books </h2>

    <!-- <input type="checkbox" ng-model="hideShow" ng-init="hideShow = false"></input> -->
    <input type = "button" value = "Add Book"ng-click="hideShow=(hideShow ? false : true)"> </input>
     <div ng-app = "mainApp" ng-controller = "bookController" ng-if="hideShow">
             Enter book name: <input type = "text" ng-model = "book.name"><br>
             Enter book category: <input type = "text" ng-model = "book.category"><br>
             Enter book price: <input type = "text" ng-model = "book.price"><br>
             Enter book author: <input type = "text" ng-model = "book.author"><br>


             You are entering book: {{book.bookDetails()}}
     </div>

    <script>
             var mainApp = angular.module("mainApp", []);

             mainApp.controller('bookController', function($scope) {
                $scope.book = {
                   name: "",
                   category: "",
                   price:"",
                   author: "",


                   bookDetails: function() {
                      var bookObject;
                      bookObject = $scope.book;
                      return "Book name: " + bookObject.name +  '\n' + "Book category: " + bookObject.category + "  \n" + "Book price: " + bookObject.price + "  \n" + "Book Author: " + bookObject.author;
                   }

                };
             });
    </script>

    <h2> Albums </h2>
    <input type = "button" value = "Add Album"ng-click="hideShow2=(hideShow2 ? false : true)"> </input>
     <div ng-app = "mainApp" ng-controller = "albumController" ng-if="hideShow2">
             Enter Album name: <input type = "text" ng-model = "album.name"><br>
             Enter Album category: <input type = "text" ng-model = "album.category"><br>
             Enter Album price: <input type = "text" ng-model = "album.price"><br>
             Enter Album singer: <input type = "text" ng-model = "album.singer"><br>


             You are entering Album: {{album.albumDetails()}}
     </div>

    <script>
             //no need to declare this again ;)
             //var mainApp = angular.module("mainApp", []);

             mainApp.controller('albumController', function($scope) {
                $scope.album = {
                   name: "",
                   category: "",
                   price:"",
                   singer: "",

                   albumDetails: function() {
                      var albumObject;
                      albumObject = $scope.album;
                      return "Album name: " + albumObject.name +  '\n' + "album category: " + albumObject.category + "\n" + "Book price: " + albumObject.price + "\n" + "Album Singer: " + albumObject.singer;
                   }
                };
             });
    </script>

    </body>
    </html>
Abdallah Okasha
sumber
2

Saya hanya meletakkan satu deklarasi sederhana dari aplikasi

var app = angular.module("app", ["xeditable"]);

Kemudian saya membangun satu layanan dan dua pengontrol

Untuk setiap pengontrol saya memiliki garis di JS

app.controller('EditableRowCtrl', function ($scope, CRUD_OperService) {

Dan di HTML saya mendeklarasikan cakupan aplikasi di div sekitarnya

<div ng-app="app">

dan setiap cakupan pengontrol secara terpisah di div sekitarnya sendiri (dalam div aplikasi)

<div ng-controller="EditableRowCtrl">

Ini bekerja dengan baik

tepuk capozzi
sumber
0

Anda juga bisa menyematkan semua tampilan template Anda ke file html utama Anda. Sebagai contoh:

<body ng-app="testApp">
  <h1>Test App</h1>
  <div ng-view></div>
  <script type = "text/ng-template" id = "index.html">
    <h1>Index Page</h1>
    <p>{{message}}</p>
  </script>
  <script type = "text/ng-template" id = "home.html">
    <h1>Home Page</h1>
    <p>{{message}}</p>
  </script>
</body>

Dengan cara ini jika setiap template membutuhkan pengontrol yang berbeda maka Anda masih dapat menggunakan angular-router. Lihat bagian ini untuk contoh kerja http://plnkr.co/edit/9X0fT0Q9MlXtHVVQLhgr?p=preview

Dengan cara ini setelah aplikasi dikirim dari server ke klien Anda, itu sepenuhnya mandiri dengan asumsi bahwa itu tidak perlu membuat permintaan data apa pun, dll.

Daimonos
sumber