วิธีกำหนดแอพเชิงมุมสองแอพ / โมดูลในหน้าเดียว


118

ฉันกำลังพยายามเพิ่มแอพ / โมดูลเชิงมุมสองตัวในหน้าเดียว ใน fiddles ด้านล่างคุณจะเห็นว่าเฉพาะโมดูลแรกที่อ้างอิงในโค้ด html เท่านั้นที่จะทำงานได้อย่างถูกต้องในขณะที่มุมที่สองไม่รู้จัก

ในซอนี้เราสามารถดำเนินการตามdoSearch2วิธีการเท่านั้นในขณะที่ในซอนี้doSearchวิธีการเท่านั้นที่ทำงานได้อย่างถูกต้อง

ฉันกำลังมองหาวิธีการวางโมดูลเชิงมุมสองโมดูลให้ถูกต้องในหน้าเดียว

คำตอบ:


123

AngularJS แอปพลิเคชันเดียวเท่านั้นที่สามารถบูตอัตโนมัติต่อเอกสาร HTML ngApp แรกที่พบในเอกสารจะถูกใช้เพื่อกำหนดองค์ประกอบรูทเพื่อบูตอัตโนมัติเป็นแอปพลิเคชัน ในการเรียกใช้หลายแอปพลิเคชันในเอกสาร HTML คุณต้องบูตสแตรปด้วยตนเองโดยใช้ angular.bootstrap แทน แอปพลิเคชัน AngularJS ไม่สามารถซ้อนกันภายใน - http://docs.angularjs.org/api/ng.directive:ngApp

ดูสิ่งนี้ด้วย


@MarkRajcok ดังนั้นการมีโมดูลเดียวต่อเอกสาร HTML เป็นแนวทางปฏิบัติที่ดีหรือไม่? ตัวอย่าง "Wire up a Backend" ในชุดหน้า AngularJS หลักng-app="project"และระบุว่า "สิ่งนี้ช่วยให้คุณมีโมดูลที่ทำงานในส่วนต่างๆของหน้า" แต่เอกสาร ngApp ระบุว่า "สามารถใช้ได้เพียงคำสั่งเดียวต่อเอกสาร HTML"
theblang

9
@mattblang โมดูลเชื่อมโยงกับแอปพลิเคชัน Angular ไม่ใช่เอกสาร HTML จริงๆ โดยปกติคุณต้องการเพียงหนึ่งแอพต่อหนึ่งหน้า / เอกสาร แต่ถ้าคุณต้องการเรียกใช้แอพพลิเคชั่น Angular หลายตัว (ซึ่งแต่ละแอพสามารถใช้หนึ่งโมดูลหรือมากกว่านั้นได้) ในหน้า / เอกสารเดียวกันคุณจะต้องบูตสแตรปด้วยตนเอง - - อย่าใช้ng-app(เพราะมันใช้ไม่ได้) ng-appสามารถใช้ได้เพียงครั้งเดียวต่อเอกสาร HTML มันเป็นเพียงการตัดบทหากคุณมีแอปเดียวในหน้าเว็บซึ่งเป็นกรณีปกติ
Mark Rajcok

1
มีตัวอย่างนี้หรือไม่? ฉันเห็นเอกสาร api บูสต์แรปสั้น ๆ แต่ไม่สามารถใช้งานได้ ฉันใช้ googled สิ่งนี้มาระยะหนึ่งแล้วและดูเหมือนจะไม่มีตัวอย่างการใช้งานแม้แต่ชิ้นเดียว นอกจากนี้ในโลกนี้จะทำงานกับเส้นทางได้อย่างไร? เห็นได้ชัดว่ามีปัญหาการปะทะกัน
Robert Christian

นอกจากนี้ฉันชอบวิธีการใช้ ng-app ที่แสดงให้นักพัฒนารายอื่นเห็นว่าส่วนใดของหน้าถูกควบคุมโดยโมดูลใด ไม่มีวิธีใดที่จะใช้มาร์กอัปบนหน้าเพื่อทำสิ่งนี้ได้? หรืออย่างน้อยคำแนะนำบางอย่างในมาร์กอัป?
chrismarx

1
สองย่อหน้าแรกสำหรับคำสั่ง ng-app บอกว่าทั้งหมด - docs.angularjs.org/api/ng.directive:ngApp
simo

38

ฉันสร้างคำสั่งทางเลือกที่ไม่มีngAppข้อ จำกัด เรียกว่าngModule. นี่คือลักษณะของโค้ดที่คุณใช้เมื่อคุณใช้งาน:

<!DOCTYPE html>
<html>
    <head>
        <script src="angular.js"></script>
        <script src="angular.ng-modules.js"></script>
        <script>
          var moduleA = angular.module("MyModuleA", []);
          moduleA.controller("MyControllerA", function($scope) {
              $scope.name = "Bob A";
          });

          var moduleB = angular.module("MyModuleB", []);
          moduleB.controller("MyControllerB", function($scope) {
              $scope.name = "Steve B";
          });
        </script>
    </head>
    <body>
        <div ng-modules="MyModuleA, MyModuleB">
            <h1>Module A, B</h1>
            <div ng-controller="MyControllerA">
                {{name}}
            </div>
            <div ng-controller="MyControllerB">
                {{name}}
            </div>
        </div>

        <div ng-module="MyModuleB">
            <h1>Just Module B</h1>
            <div ng-controller="MyControllerB">
                {{name}}
            </div>
        </div>
    </body>
</html>

คุณสามารถรับซอร์สโค้ดได้ที่:

http://www.simplygoodcode.com/2014/04/angularjs-getting-around-ngapp-limitations-with-ngmodule/

โดยพื้นฐานแล้วเป็นรหัสเดียวกับที่ AngularJS ใช้ภายในโดยไม่มีข้อ จำกัด


luisperezphd: ฉันอ่านบล็อกโพสต์ของคุณ มีวิธีใดบ้างในการซ้อนแอพ (เช่นตัวสร้างวิดเจ็ตที่มีวิดเจ็ตที่โหลด AJAX) หรือตรวจสอบว่าเพจมีแอพอยู่แล้วหรือไม่และอัดแอพอื่นเป็นการอ้างอิงของแอพแรก ฉันเพิ่งโพสต์คำถามของฉันที่นี่พร้อมรายละเอียดเพิ่มเติมว่าฉันพยายามทำอะไรให้สำเร็จ ขอบคุณ!
Daniel Bonnell

@ACIDSTEALTH ความจริงที่ว่า AngularJS รายงานว่าองค์ประกอบนั้นบูตแล้วหมายความว่าต้องมีวิธีใดที่จะบอกได้ - แม้ว่ารหัสนั้นอาจอยู่ภายในของ AngularJS ก็ตาม หากต้องการทราบว่าคุณสามารถอ้างอิง AngularJS และเบรกพอยต์เวอร์ชันที่ไม่มีการปิดย่อของข้อผิดพลาดนั้นเพื่อดูเงื่อนไข if จากสิ่งที่ฉันสามารถทำได้จากลิงก์คำถาม StackOverflow ของคุณดูเหมือนว่าคุณต้องการ "ฉีด" โมดูลแบบไดนามิกในขณะรันไทม์ ถ้าเป็นเช่นนั้นคุณอาจต้องการอ่านบทความนี้: weblogs.asp.net/dwahlin/…
Luis Perez

เฮ้ @LuisPerez ฉันตรวจสอบเว็บไซต์ของคุณแล้ว ฉันเหนื่อยบนเครื่องของฉัน angularJS ตรวจไม่พบ "ng-module" / "ng-module" ฉันต้องการการอ้างอิงใด ๆ ที่รวมอยู่ในไฟล์ของฉันหรือไม่?
sujay kodamala

ใช่ @sujaykodamala, ngModule ไม่ได้สร้างไว้ใน AngularJS มันเป็นคำสั่งที่ฉันสร้างขึ้น คุณสามารถดาวน์โหลดได้จาก GitHub คุณสามารถค้นหาได้ที่นี่: github.com/luisperezphd/ngModule
Luis Perez

สวัสดี @Luis Perez! ฉันกำลังตรวจสอบโพสต์บล็อกของคุณและพวกเขายอดเยี่ยมมาก หากคุณมีเวลาโปรดตรวจสอบโพสต์ของฉันที่นี่เพื่อแก้ไขปัญหาได้ไหม- stackoverflow.com/questions/46952478/… ขอบคุณ
user8512043

19

ทำไมคุณถึงต้องการใช้ [ng-app] หลายตัว เนื่องจาก Angular กลับมาทำงานอีกครั้งโดยใช้โมดูลคุณจึงสามารถใช้แอพที่ใช้การอ้างอิงหลายตัวได้

javascript:

// setter syntax -> initializing other module for demonstration
angular.module('otherModule', []);

angular.module('app', ['otherModule'])
.controller('AppController', function () {
    // ...do something
});

// getter syntax
angular.module('otherModule')
.controller('OtherController', function () {
    // ...do something
});

HTML:

<div ng-app="app">
    <div ng-controller="AppController">...</div>
    <div ng-controller="OtherController">...</div>
</div>

แก้ไข

โปรดทราบว่าหากคุณต้องการใช้คอนโทรลเลอร์ภายในคอนโทรลเลอร์คุณต้องใช้ไวยากรณ์ของคอนโทรลเลอร์ดังนี้:

<div ng-app="app">
    <div ng-controller="AppController as app">
        <div ng-controller="OtherController as other">...</div>
    </div>
</div>

Uncaught Error: [$ injector: modulerr] error.angularjs.org/1.3.14/$injector/…… criptMinification% 2Fbower_components% 2Fangular% 2Fangular.min.js% 3A17% 3A381)
Anandaraja_Srinivasan

คุณเคยพยายามสลับลำดับของ 2 โมดูลหรือไม่ ('otherModule' before 'app') เพราะฉันใช้วิธีนี้บ่อยมากและมันก็ทำงานได้อย่างสมบูรณ์แบบ ...
Monkey Monk

1
ตกลง ! ฉันพบข้อผิดพลาดในตัวอย่าง Javascript ที่ฉันระบุ คิดว่าคงได้รับการแก้ไขแล้ว! สำหรับการบันทึกฉันจะใช้ไวยากรณ์ setter ใน 2 ตำแหน่งสำหรับโมดูลเดียวกัน ... ซึ่งเห็นได้ชัดว่าไม่อนุญาต! :-)
Monkey Monk

วิธีที่เราจะทำ
Harry Bosh

9

คุณสามารถบูตแอปพลิเคชั่นเชิงมุมได้หลายตัว แต่:

1) คุณต้องบูตด้วยตนเอง

2) คุณไม่ควรใช้ "document" เป็นรูท แต่โหนดที่มีอินเทอร์เฟซเชิงมุมสำหรับ:

var todoRootNode = jQuery('[ng-controller=TodoController]');
angular.bootstrap(todoRootNode, ['TodoApp']);

นี้จะปลอดภัย


3

การบูตด้วยตนเองทั้งสองโมดูลจะทำงาน ดูนี่สิ

  <!-- IN HTML -->
  <div id="dvFirst">
    <div ng-controller="FirstController">
      <p>1: {{ desc }}</p>
    </div>
  </div>

  <div id="dvSecond">
    <div ng-controller="SecondController ">
      <p>2: {{ desc }}</p>
    </div>
  </div>



// IN SCRIPT       
var dvFirst = document.getElementById('dvFirst');
var dvSecond = document.getElementById('dvSecond');

angular.element(document).ready(function() {
   angular.bootstrap(dvFirst, ['firstApp']);
   angular.bootstrap(dvSecond, ['secondApp']);
});

นี่คือลิงค์ไปยัง Plunker http://plnkr.co/edit/1SdZ4QpPfuHtdBjTKJIu?p=preview

หมายเหตุ:ใน html ไม่มีng-appไฟล์. idถูกนำมาใช้แทน


0

ฉันสร้าง POC สำหรับแอปพลิเคชันเชิงมุมโดยใช้โมดูลและเราเตอร์หลายตัวเพื่อซ้อนแอปย่อยในแอปหน้าเดียว คุณสามารถรับซอร์สโค้ดได้ที่: https://github.com/AhmedBahet/ng-sub-apps

หวังว่านี่จะช่วยได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.