Bagaimana cara membuat file pengontrol AngularJS yang terpisah?

315

Saya memiliki semua pengontrol AngularJS saya dalam satu file, controllers.js. File ini disusun sebagai berikut:

angular.module('myApp.controllers', [])
  .controller('Ctrl1', ['$scope', '$http', function($scope, $http) {    
  }])
  .controller('Ctrl2', ['$scope', '$http', function($scope, $http) }
  }])

Yang ingin saya lakukan adalah meletakkan Ctrl1 dan Ctrl2 ke file terpisah. Saya kemudian akan memasukkan kedua file di index.html saya, tetapi bagaimana seharusnya itu disusun? Saya mencoba melakukan beberapa hal seperti ini dan melempar kesalahan di konsol browser web dengan mengatakan tidak dapat menemukan pengontrol saya. Ada petunjuk?

Saya mencari StackOverflow dan menemukan pertanyaan serupa - namun, sintaks ini menggunakan kerangka kerja yang berbeda (CoffeeScript) di atas Angular, jadi saya belum bisa mengikuti.


AngularJS: Bagaimana cara membuat pengontrol di banyak file

Beebunny
sumber

Jawaban:

399

File satu:

angular.module('myApp.controllers', []);

File dua:

angular.module('myApp.controllers').controller('Ctrl1', ['$scope', '$http', function($scope, $http){

}]);

File tiga:

angular.module('myApp.controllers').controller('Ctrl2', ['$scope', '$http', function($scope, $http){

}]);

Sertakan dalam urutan itu. Saya merekomendasikan 3 file sehingga deklarasi modul itu sendiri.


Adapun struktur folder ada banyak banyak pendapat tentang subjek, tetapi keduanya cukup bagus

https://github.com/angular/angular-seed

http://briantford.com/blog/huuuuuge-angular-apps.html

Bola mata baru
sumber
1
Jika OP mengindikasikan kebingungan tentang sintaks CoffeeScript, mungkin lebih baik tidak menggunakannya dalam jawaban Anda?
Andrew
3
@Andrew imho bantuan masa depan dan membuat catatan solusi adalah apa SO sebenarnya semua tentang, bukan q dan seorang pria tanpa persiapan.
Fresheyeball
2
@RuslanIsmagilov appCtrladalah global Anda window.appCtrl. Itu bukan praktik yang baik.
Fresheyeball
1
@Fresheyeball, masalah dari pendekatan ini adalah urutan impor dalam index.html penting, jika tidak, kesalahan emit sudut.
Deoxyseia
2
@ hendryau, yah saya sedang bekerja dengan nama modul yang ada di OP. Yang mengatakan, beberapa merasa lebih baik secara organisasi, memiliki beberapa modul spasi nama, daripada modul aplikasi pusat.
Fresheyeball
177

Menggunakan API angular.module dengan array di bagian akhir akan memberi tahu angular untuk membuat modul baru:

myApp.js

// It is like saying "create a new module"
angular.module('myApp.controllers', []); // Notice the empty array at the end here

Menggunakannya tanpa array sebenarnya adalah fungsi pengambil. Jadi untuk memisahkan pengontrol Anda, Anda dapat melakukan:

Ctrl1.js

// It is just like saying "get this module and create a controller"
angular.module('myApp.controllers').controller('Ctrlr1', ['$scope', '$http', function($scope, $http) {}]);

Ctrl2.js

angular.module('myApp.controllers').controller('Ctrlr2', ['$scope', '$http', function($scope, $http) {}]);

Selama impor javascript Anda, pastikan myApp.js adalah setelah AngularJS tetapi sebelum pengontrol / layanan / dll ... jika tidak, sudut akan tidak dapat menginisialisasi pengontrol Anda.

Jimmy Au
sumber
di mana saya harus menulis dependensi saya. var myapp = angular.module ('demo', ['ngRoute', 'ngCookies', 'ui.bootstrap', 'nvd3ChartDirectives', 'ui-rangeSlider', 'textAngular', 'angularTreeview']);
vipin
@vipin seperti apa yang Anda ketikkan, tetapi pastikan itu di atas pengontrol, layanan, dll. Secara teknis Anda tidak perlu mendeklarasikan var myapp = ...; karena angular akan menyimpannya untuk Anda.
Jimmy Au
@JimmyAu Di mana Ctrl1.js dan Ctrl2.js dimuat sehingga halaman dapat menggunakannya? Saya memiliki myApp.js dimuat setelah sudut, tetapi halaman tidak dapat menemukan pengendali. Apakah saya harus menambahkannya secara eksplisit sebagai skrip pada tampilan yang memerlukannya? Atau apakah saya masih harus memasukkan setiap file pengontrol pada setiap halaman?
Sinaesthetic
2
Terima kasih telah menjelaskan mengapa hanya panggilan pertama yang perlu [].
Jim B.
49

Meskipun kedua jawaban secara teknis benar, saya ingin memperkenalkan pilihan sintaks yang berbeda untuk jawaban ini. Imho ini membuatnya lebih mudah untuk membaca apa yang terjadi dengan injeksi, membedakan antara dll.

File Satu

// Create the module that deals with controllers
angular.module('myApp.controllers', []);

File Dua

// Here we get the module we created in file one
angular.module('myApp.controllers')

// We are adding a function called Ctrl1
// to the module we got in the line above
.controller('Ctrl1', Ctrl1);

// Inject my dependencies
Ctrl1.$inject = ['$scope', '$http'];

// Now create our controller function with all necessary logic
function Ctrl1($scope, $http) {
  // Logic here
}

File Tiga

// Here we get the module we created in file one
angular.module('myApp.controllers')

// We are adding a function called Ctrl2
// to the module we got in the line above
.controller('Ctrl2', Ctrl2);

// Inject my dependencies
Ctrl2.$inject = ['$scope', '$http'];

// Now create our controller function with all necessary logic
function Ctrl2($scope, $http) {
  // Logic here
}
jason328
sumber
Menarik, itu membuat saya tidak pergi ke beberapa file untuk mendaftarkan controller
mrwaim
4
Saya melihat banyak pengkodean seperti ini. Apa keuntungannya? memiliki $ inject dan fungsi yang terpisah.
Alaksandar Jesus Gene
2
Saya percaya itu membuat kode lebih mudah dibaca. Saya tahu persis apa yang disuntikkan. Anggap saja sebagai "pemisahan keprihatinan" berdasarkan garis demi garis.
jason328
2
Kode seperti ini tidak hanya menghasilkan kode yang lebih mudah dibaca, jauh lebih mudah untuk di-debug, dan mengurangi jumlah kode panggilan balik bersarang (lihat github.com/johnpapa/angular-styleguide/blob/master/a1/… )
rfornal
Jika saya bisa memberi ini 1000 kali, saya akan - bravo!
Dan Chase
17

Bagaimana dengan solusi ini? Modul dan Pengendali dalam File (di akhir halaman) Ini berfungsi dengan banyak pengontrol, arahan, dan sebagainya:

app.js

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

myCtrl.js

app.controller("myCtrl", function($scope) { ..});

html

<script src="app.js"></script>
<script src="myCtrl.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">

Google juga memiliki Rekomendasi Praktik Terbaik untuk Struktur Aplikasi Sudut Saya sangat suka mengelompokkan berdasarkan konteks. Tidak semua html dalam satu folder, tetapi misalnya semua file untuk masuk (html, css, app.js, controller.js, dan sebagainya). Jadi jika saya mengerjakan modul, semua arahan lebih mudah ditemukan.

schasoli
sumber
3

Untuk singkatnya, inilah sampel ES2015 yang tidak bergantung pada variabel global

// controllers/example-controller.js

export const ExampleControllerName = "ExampleController"
export const ExampleController = ($scope) => {
  // something... 
}

// controllers/another-controller.js

export const AnotherControllerName = "AnotherController"
export const AnotherController = ($scope) => {
  // functionality... 
}

// app.js

import angular from "angular";

import {
  ExampleControllerName,
  ExampleController
} = "./controllers/example-controller";

import {
  AnotherControllerName,
  AnotherController
} = "./controllers/another-controller";

angular.module("myApp", [/* deps */])
  .controller(ExampleControllerName, ExampleController)
  .controller(AnotherControllerName, AnotherController)
Pete TNT
sumber
1
Anda dapat menyimpan sedikit pengetikan jika Anda menggunakan fungsi bernama .. mereka memiliki properti praktis name.. jadi Anda bisa menggunakan ExampleCtrl.namealih-alih dupl .. melipatgandakannya.
Antti Pihlaja
0

Tidak begitu anggun, tetapi sangat sederhana dalam solusi implementasi - menggunakan variabel global.

Dalam file "pertama":


window.myApp = angular.module("myApp", [])
....

di "kedua", "ketiga", dll:


myApp.controller('MyController', function($scope) {
    .... 
    }); 
pengguna3682640
sumber
saya menggunakan kode ini tetapi masih tidak dapat memuat pengontrol saya? itu melempar kesalahan: Kesalahan: [ng: areq] Argumen 'ProductCtrl' bukan fungsi, tidak terdefinisi.
QViet
7
ini praktik yang sangat buruk
Brendan
@ Kim Jong Un Anda akan melihat kesalahan itu jika Anda tidak menambah / menggabungkan controller ke modul yang Anda buat. Jadi itu akan berhasil jika Anda menggunakan sintaks berikut:angular.module('myApp').controller('ProductCtrl', ['$scope', '$http', function($scope, $http){ //Your ProductCtrl code goes here }]);
Devner
1
@ Brendan, hanya menyatakan bahwa ada sesuatu yang merupakan praktik buruk lebih baik daripada tidak sama sekali - tetapi tidak banyak. Beritahu kami mengapa itu adalah praktik buruk akan membantu orang lain.
Mawg mengatakan mengembalikan Monica