Pertanyaan ini sudah lama tetapi saya berjuang untuk waktu yang lama mencoba mendapatkan jawaban untuk masalah ini yang akan bekerja untuk kebutuhan saya dan tidak mudah menemukannya. Saya percaya solusi saya berikut ini jauh lebih baik daripada yang diterima saat ini, mungkin karena sudut telah menambahkan fungsionalitas sejak pertanyaan ini awalnya diajukan.
Jawaban singkat, menggunakan metode Module.value memungkinkan Anda untuk meneruskan data ke konstruktor pengontrol.
Lihat penyedot saya di sini
Saya membuat objek model, lalu mengaitkannya dengan pengontrol modul, merujuknya dengan nama 'model'
HTML / JS
<html>
<head>
<script>
var model = {"id": 1, "name":"foo"};
$(document).ready(function(){
var module = angular.module('myApp', []);
module.value('model', model);
module.controller('MyController', ['model', MyController]);
angular.bootstrap(document, ['myApp']);
});
function confirmModelEdited() {
alert("model name: " + model.name + "\nmodel id: " + model.id);
}
</script>
</head>
<body >
<div ng-controller="MyController as controller">
id: {{controller.model.id}} <br>
name: <input ng-model="controller.model.name"/>{{controller.model.name}}
<br><button ng-click="controller.incrementId()">increment ID</button>
<br><button onclick="confirmModelEdited()">confirm model was edited</button>
</div>
</body>
</html>
Konstruktor di controller saya kemudian menerima parameter dengan 'model' pengidentifikasi yang sama yang kemudian dapat diakses.
Pengendali
function MyController (model) {
this.model = model;
}
MyController.prototype.incrementId = function() {
this.model.id = this.model.id + 1;
}
Catatan:
Saya menggunakan inisialisasi manual bootstrap , yang memungkinkan saya untuk menginisialisasi model saya sebelum mengirimnya ke sudut. Ini memainkan jauh lebih baik dengan kode yang ada, karena Anda dapat menunggu untuk menyiapkan data yang relevan dan hanya mengkompilasi bagian sudut dari aplikasi Anda sesuai permintaan saat Anda mau.
Dalam plunker saya telah menambahkan tombol untuk mengingatkan nilai-nilai objek model yang awalnya didefinisikan dalam javascript dan diteruskan ke sudut, hanya untuk mengonfirmasi bahwa sudut benar-benar merujuk objek model, daripada menyalinnya dan bekerja dengan salinan.
Di baris ini:
module.controller('MyController', ['model', MyController]);
Saya meneruskan objek MyController ke fungsi Module.controller, daripada mendeklarasikan sebagai fungsi inline. Saya pikir ini memungkinkan kita untuk mendefinisikan objek controller kita dengan lebih jelas, tetapi dokumentasi Angular cenderung melakukannya secara inline, jadi saya pikir ini memerlukan klarifikasi.
Saya menggunakan sintaks "controller as" dan memberikan nilai ke properti "this" dari MyController, daripada menggunakan variabel "$ scope". Saya percaya ini akan bekerja dengan baik menggunakan $ scope juga, tugas controller akan terlihat seperti ini:
module.controller('MyController', ['$scope', 'model', MyController]);
dan konstruktor controller akan memiliki tanda tangan seperti ini:
function MyController ($scope, model) {
Jika karena alasan apa pun yang Anda inginkan, Anda juga bisa melampirkan model ini sebagai nilai dari modul kedua, yang kemudian Anda lampirkan sebagai ketergantungan pada modul utama Anda.
Saya percaya solusinya jauh lebih baik daripada yang diterima saat ini karena
- Model yang diteruskan ke controller sebenarnya adalah objek javascript, bukan string yang dievaluasi. Ini adalah referensi yang benar ke objek dan perubahan itu mempengaruhi referensi lain ke objek model ini.
- Angular mengatakan bahwa penggunaan jawaban ng-init yang diterima adalah penyalahgunaan, yang tidak dilakukan solusi ini.
Cara Angular tampaknya bekerja di sebagian besar semua contoh lain yang pernah saya lihat memiliki controller mendefinisikan data model, yang tidak pernah masuk akal bagi saya, tidak ada pemisahan antara model dan controller, yang tidak benar-benar tampak seperti MVC bagiku. Solusi ini memungkinkan Anda untuk benar-benar memiliki objek model yang benar-benar terpisah yang Anda lewati ke controller. Yang juga perlu diperhatikan, jika Anda menggunakan perintah ng-include Anda dapat meletakkan semua html sudut Anda dalam file terpisah, sepenuhnya memisahkan tampilan model Anda dan pengontrol menjadi potongan modular terpisah.