คำถามนี้เก่า แต่ฉันพยายามเป็นเวลานานในการพยายามหาคำตอบสำหรับปัญหานี้ที่จะใช้งานได้ตามความต้องการของฉันและไม่สามารถหาได้ง่าย ฉันเชื่อว่าวิธีแก้ไขปัญหาต่อไปนี้ดีกว่าโซลูชันที่ยอมรับในปัจจุบันบางทีอาจเป็นเพราะเชิงมุมได้เพิ่มฟังก์ชันการทำงานเนื่องจากคำถามนี้ถูกวางเดิม
คำตอบสั้น ๆ โดยใช้วิธีการ Module.value ช่วยให้คุณสามารถส่งผ่านข้อมูลไปยังตัวสร้างคอนโทรลเลอร์
ดูพลั่วของฉันที่นี่
ฉันสร้างโมเดลวัตถุจากนั้นเชื่อมโยงกับคอนโทรลเลอร์ของโมดูลโดยอ้างอิงกับชื่อ '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>
คอนสตรัคในตัวควบคุมของฉันนั้นยอมรับพารามิเตอร์ที่มี 'ตัวจำลอง' ตัวระบุเดียวกันซึ่งมันสามารถเข้าถึงได้
ตัวควบคุม
function MyController (model) {
this.model = model;
}
MyController.prototype.incrementId = function() {
this.model.id = this.model.id + 1;
}
หมายเหตุ:
ฉันใช้การกำหนดค่าเริ่มต้นด้วยตนเองของการบูตสแตรปปิ้งซึ่งทำให้ฉันสามารถเริ่มต้นแบบของฉันก่อนส่งไปยังเชิงมุม สิ่งนี้เล่นได้ดีกว่าด้วยรหัสที่มีอยู่ในขณะที่คุณสามารถรอการตั้งค่าข้อมูลที่เกี่ยวข้องของคุณและรวบรวมเฉพาะชุดย่อยเชิงมุมของแอปของคุณตามต้องการเมื่อคุณต้องการ
ในพลั่วเกอร์ฉันได้เพิ่มปุ่มเพื่อแจ้งเตือนค่าของวัตถุต้นแบบที่กำหนดไว้ในจาวาสคริปต์และส่งผ่านไปยังเชิงมุมเพียงเพื่อยืนยันว่าเชิงมุมหมายถึงการอ้างอิงวัตถุจำลองอย่างแท้จริงแทนที่จะคัดลอกและทำงานกับสำเนา
ในบรรทัดนี้:
module.controller('MyController', ['model', MyController]);
ฉันส่งวัตถุ MyController ไปยังฟังก์ชัน Module.controller แทนที่จะประกาศว่าเป็นฟังก์ชันอินไลน์ ฉันคิดว่านี่ช่วยให้เรากำหนดวัตถุคอนโทรลเลอร์ได้ชัดเจนยิ่งขึ้น แต่เอกสารเชิงมุมมีแนวโน้มที่จะทำแบบอินไลน์ดังนั้นฉันคิดว่ามันชัดเจน
ฉันใช้ไวยากรณ์ "controller as" และกำหนดค่าให้กับคุณสมบัติ "this" ของ MyController แทนที่จะใช้ตัวแปร "$ scope" ฉันเชื่อว่าสิ่งนี้จะทำงานได้ดีโดยใช้ $ scope เช่นกันการกำหนดคอนโทรลเลอร์จะมีลักษณะดังนี้:
module.controller('MyController', ['$scope', 'model', MyController]);
และตัวสร้างคอนโทรลเลอร์จะมีลายเซ็นดังนี้:
function MyController ($scope, model) {
หากคุณต้องการด้วยเหตุผลใดก็ตามคุณสามารถแนบโมเดลนี้เป็นค่าของโมดูลที่สองซึ่งคุณต้องแนบเป็นการอ้างอิงกับโมดูลหลักของคุณ
ฉันเชื่อว่าวิธีแก้ปัญหาของเขาดีกว่าที่ยอมรับในปัจจุบันมากเพราะ
- รูปแบบที่ส่งผ่านไปยังคอนโทรลเลอร์เป็นวัตถุจาวาสคริปต์ไม่ใช่สตริงที่ได้รับการประเมิน มันคือการอ้างอิงที่แท้จริงไปยังวัตถุและการเปลี่ยนแปลงที่มีผลต่อการอ้างอิงอื่น ๆ ไปยังวัตถุรูปแบบนี้
- Angular กล่าวว่าการใช้คำตอบที่ยอมรับของ ng-init นั้นเป็นการใช้ในทางที่ผิดซึ่งโซลูชันนี้ไม่ได้ทำ
วิธีที่แองกูลาร์ดูเหมือนจะทำงานในตัวอย่างอื่น ๆ ส่วนใหญ่ทั้งหมดที่ฉันเคยเห็นมีคอนโทรลเลอร์กำหนดข้อมูลของโมเดลซึ่งไม่สมเหตุสมผลสำหรับฉันไม่มีการแยกระหว่างโมเดลและคอนโทรลเลอร์ที่ดูเหมือนจะไม่จริง MVC กับฉัน วิธีการแก้ปัญหานี้ช่วยให้คุณมีรูปแบบวัตถุแยกต่างหากที่คุณส่งผ่านเข้าไปในคอนโทรลเลอร์ นอกจากนี้ถ้าคุณใช้คำสั่ง ng-include คุณสามารถใส่ html เชิงมุมทั้งหมดของคุณลงในไฟล์แยกกันแยกมุมมองแบบจำลองและตัวควบคุมออกเป็นชิ้นส่วนแยกต่างหาก