ฉันจะทดสอบบริการ AngularJS จากคอนโซลได้อย่างไร


395

ฉันมีบริการเช่น:

angular.module('app').factory('ExampleService', function(){
  this.f1 = function(world){
    return 'Hello '+world;
  }
  return this;
})

ฉันต้องการทดสอบจากคอนโซล JavaScriptและเรียกใช้ฟังก์ชันf1()ของบริการ

ฉันจะทำสิ่งนั้นได้อย่างไร

คำตอบ:


713

TLDR: ในหนึ่งบรรทัดคำสั่งที่คุณกำลังมองหา:

angular.element(document.body).injector().get('serviceName')

ดำน้ำลึก

AngularJS ใช้การพึ่งพาการฉีด (DI)เพื่อฉีดบริการ / โรงงานลงในส่วนประกอบคำสั่งและบริการอื่น ๆ ของคุณ ดังนั้นสิ่งที่คุณต้องทำเพื่อรับบริการคือการรับหัวฉีดของ AngularJS ก่อน (หัวฉีดรับผิดชอบการเดินสายขึ้นต่อกันทั้งหมดและให้ส่วนประกอบ)

ในการรับหัวฉีดของแอปของคุณคุณต้องคว้ามันจากองค์ประกอบที่มีการจัดการเชิงมุม ตัวอย่างเช่นหากแอปของคุณลงทะเบียนในองค์ประกอบร่างกายที่คุณโทรinjector = angular.element(document.body).injector()

จากการดึงข้อมูลinjectorคุณสามารถรับบริการที่คุณต้องการได้injector.get('ServiceName')

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


เคล็ดลับที่มีประโยชน์อีกประการหนึ่งเพื่อให้ได้$scopeองค์ประกอบเฉพาะ เลือกองค์ประกอบด้วยเครื่องมือตรวจสอบ DOMของเครื่องมือนักพัฒนาของคุณแล้วเรียกใช้บรรทัดต่อไปนี้ ( $0เป็นองค์ประกอบที่เลือกเสมอ):
angular.element($0).scope()


70
ฉันต้องทำเช่นนี้เพื่อให้มันใช้งานได้ BTW angular.element('*[ng-app]').injector()ควรใช้งานได้กับทุกกรณี
Francesc Rosas

4
หากคุณได้รับข้อผิดพลาด 'ตัวเลือกที่ไม่ได้ใช้งาน' กำลังเรียกใช้ angular.element ('html') คุณสามารถใช้คุณลักษณะ Chrome $ 0 ได้ เลือกองค์ประกอบ HTML ไปที่คอนโซลและเรียกใช้ angular.element ($ 0). injector ()
Marek

9
documentยังใช้งานได้:angular.element(document).injector().get('serviceName')
Tamlyn

1
FYI ฉันต้องใช้ document.body บน chrome
Kevin

5
FYI ฉันต้องการใช้ $ location services แต่ในที่สุดฉันก็จำเป็นต้องใช้ใน scope.apply ฉันรู้ว่านี่เป็นเอกสารที่ดี แต่มันทำให้จิตใจของฉันลื่น ในหนึ่งบรรทัด angular.element (เอกสาร) .scope (). $ Apply (angular.element (เอกสาร). injector (). get ('$ location'). พา ธ ('/ my / angular / url')
acid_crucifix

25

ก่อนอื่นบริการของคุณที่ได้รับการแก้ไขแล้ว

ก)

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

app.factory('ExampleService',function(){
    return {
        f1 : function(world){
            return 'Hello' + world;
        }
    };
});

ส่งคืนวัตถุไม่มีอะไรใหม่ที่นี่

ตอนนี้วิธีการรับสิ่งนี้จากคอนโซลคือ

ข)

var $inj = angular.injector(['app']);
var serv = $inj.get('ExampleService');
serv.f1("World");

ค )

หนึ่งในสิ่งที่คุณทำที่นั่นก่อนหน้านี้คือการสันนิษฐานว่า app.factory ส่งคืนฟังก์ชันของคุณเองหรือเวอร์ชันใหม่ของมัน ซึ่งไม่ใช่กรณี เพื่อให้ได้ตัวสร้างคุณจะต้องทำ

app.factory('ExampleService',function(){
        return function(){
            this.f1 = function(world){
                return 'Hello' + world;
            }
        };
    });

สิ่งนี้จะส่งคืน Constructor ExampleService ซึ่งคุณจะต้องทำ 'new'

หรืออีกวิธีหนึ่งคือ

app.service('ExampleService',function(){
            this.f1 = function(world){
                return 'Hello' + world;
            };
    });

สิ่งนี้จะส่งคืน ExampleService () ใหม่สำหรับการฉีด


3
เมื่อฉันทำvar $inj = angular.injector(['app']);แล้วคอนโซลจะโยนError: Unknown provider: $filterProvider from appแอปหนึ่งและError: Unknown provider: $controllerProvider from appอีกแอปหนึ่ง ...
JustGoscha

@JustGoscha แอปของคุณมีการกำหนดค่าอย่างไร? นั่นคือเส้น (ที่ดูเหมือน) var app = angular.module ('แอป', []); ดูเหมือนในแอปของคุณ
ganaraj

ฉันไม่เข้าใจคำถามอย่างสมบูรณ์ .. ดูเหมือนว่าคุณจะพูดangular.module('app',[]);แล้วมีบริการตัวควบคุมและอื่น ๆ ในไฟล์ที่แตกต่างกันและพวกเขาทั้งหมดถูกกำหนดangular.module('app').factory('FeatureRegistry',function(){//code here});เช่น
JustGoscha

@ JustGoscha นี่คือสิ่งที่ฉันได้ทำการทดสอบ ฉันไปที่docs.angularjs.org/apiด้วยโครเมียม เปิดคอนโซล พิมพ์รหัสในส่วน a ของคำตอบของฉันแล้วพิมพ์รหัสในส่วน b .. คุณควรเห็น Hello World .. คุณลองทำดูได้มั้ย
ganaraj

14

@ คำตอบของ JustGoscha เป็นจุดที่ แต่ที่มากในการพิมพ์เมื่อฉันต้องการเข้าถึงดังนั้นฉันเพิ่มนี้ที่ด้านล่างของ app.js. สิ่งที่ฉันต้องพิมพ์ก็คือx = getSrv('$http')การได้รับบริการ http

// @if DEBUG
function getSrv(name, element) {
    element = element || '*[ng-app]';
    return angular.element(element).injector().get(name);
}
// @endif

มันเพิ่มลงในขอบเขตส่วนกลาง แต่เฉพาะในโหมดดีบัก ฉันใส่มันเข้าไปข้างใน@if DEBUGเพื่อที่จะไม่ได้ลงเอยด้วยรหัสการผลิต ฉันใช้วิธีนี้เพื่อลบรหัสการแก้ปัญหาจากการสร้าง prouduction


4

กรอบการทำงานของ Angularjs Dependency Injection มีหน้าที่ในการฉีดการพึ่งพาโมดูลแอพของคุณไปยังคอนโทรลเลอร์ นี่เป็นไปได้ผ่านหัวฉีด

คุณต้องระบุ ng-app ก่อนและรับหัวฉีดที่เกี่ยวข้อง แบบสอบถามด้านล่างนี้ใช้เพื่อค้นหาแอป ng ของคุณใน DOM และดึงหัวฉีด

angular.element('*[ng-app]').injector()

อย่างไรก็ตามใน Chrome คุณสามารถชี้ไปที่เป้าหมาย ng-app ดังที่แสดงด้านล่าง และใช้$0แฮ็คและปัญหาangular.element($0).injector()

เมื่อคุณมีหัวฉีดรับบริการฉีดพึ่งพาใด ๆ ดังต่อไปนี้

injector = angular.element($0).injector();
injector.get('$mdToast');

ป้อนคำอธิบายรูปภาพที่นี่

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