สับสนเกี่ยวกับการบริการเทียบกับโรงงาน


618

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

ฉันอยู่ภายใต้การสันนิษฐานว่าการบริการเป็นแบบซิงเกิลเสมอและวัตถุโรงงานใหม่จะถูกฉีดเข้าไปในตัวควบคุมทุกตัว อย่างไรก็ตามมันกลับกลายเป็นว่าวัตถุในโรงงานเป็นซิงเกิลตันด้วยหรือไม่

รหัสตัวอย่างที่จะสาธิต:

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

factories.factory('User', function () {
  return {
    first: 'John',
    last: 'Doe'
  };
});

app.controller('ACtrl', function($scope, User) {
  $scope.user = User;
});

app.controller('BCtrl', function($scope, User) {
  $scope.user = User;
});

เมื่อมีการเปลี่ยนแปลงuser.firstในACtrlปรากฎว่าuser.firstในBCtrlนอกจากนี้ยังมีการเปลี่ยนแปลงเช่นUserเป็นเดี่ยวหรือไม่?

ข้อสันนิษฐานของฉันคืออินสแตนซ์ใหม่ถูกฉีดเข้าไปในคอนโทรลเลอร์ที่มีโรงงานหรือไม่


4
ถัดจาก "module.service" และ "module.factory" มีอีก 2 วิธีในการสร้างบริการใน AngularJS สำหรับข้อมูลเพิ่มเติมตรวจสอบโดยโพสต์บล็อก: " วิธีการสร้าง (เดี่ยว) บริการ AngularJS ใน 4 วิธีที่แตกต่าง "
Emil van Galen

สำเนาซ้ำที่เป็นไปได้ของangular.service กับ angular.factory
Kaushal28

คำตอบ:


600

บริการเชิงมุมทั้งหมดเป็นซิงเกิลตัน :

เอกสาร (ดูบริการเป็น singletons ): https://docs.angularjs.org/guide/services

สุดท้ายสิ่งสำคัญคือต้องตระหนักว่าบริการเชิงมุมทั้งหมดเป็นแอปพลิเคชันเดี่ยว ซึ่งหมายความว่ามีเพียงหนึ่งอินสแตนซ์ของบริการที่กำหนดต่อหัวฉีด

โดยทั่วไปความแตกต่างระหว่างการบริการและโรงงานเป็นดังนี้:

app.service('myService', function() {

  // service is just a constructor function
  // that will be called with 'new'

  this.sayHello = function(name) {
     return "Hi " + name + "!";
  };
});

app.factory('myFactory', function() {

  // factory returns an object
  // you can run some code before

  return {
    sayHello : function(name) {
      return "Hi " + name + "!";
    }
  }
});

ตรวจสอบการนำเสนอนี้เกี่ยวกับ $ offer: http://slides.wesalvaro.com/20121113/#/

สไลด์เหล่านั้นถูกใช้ในหนึ่งในการพบปะของ AngularJs: http://blog.angularjs.org/2012/11/more-angularjs-meetup-videos.html


13
ดูstackoverflow.com/questions/15666048/…ซึ่งอธิบายความแตกต่างระหว่างการบริการโรงงานและการให้บริการ
Mark Rajcok

31
doc อย่างเป็นทางการทางอ้อม [sic! ไม่ชัดเจนเพียงพอ] บอกเป็นนัยว่าแม้ว่าคุณจะกำหนดบริการกับโรงงาน แต่ก็สร้างขึ้นเพียงครั้งเดียว ในคำอื่น ๆ มันไม่ได้สร้างขึ้นอีกครั้งตามการอ้างอิง (จุดฉีด) - สิ่งที่คุณเรียกมันว่า ทั้งสองวิธีส่งผลให้อินสแตนซ์ซิงเกิลตันต่อหัวฉีด
honzajde

3
คุณพูดว่า "service เป็นเพียงฟังก์ชั่นคอนสตรัคเตอร์ที่จะถูกเรียกด้วย" ใหม่ "" แต่ฉันคิดว่านั่นทำให้เข้าใจผิด ฉันไม่คิดว่ามันเรียกว่าใหม่อยู่เบื้องหลังผมคิดว่านักพัฒนาที่เป็นผู้รับผิดชอบสำหรับการโทรnewในนั้น
ทิม Kindberg

5
@ nfiniteloop ตรวจสอบซอร์สโค้ดใกล้กับบรรทัด 3574 โรงงานเป็นวิธี $ get ของผู้ให้บริการและบริการสร้างโรงงานโดยใช้วิธีการที่เรียก $ injector.instantiate จากฟังก์ชั่นที่มีให้ซึ่งจะเรียกใหม่ ( ดูเอกสาร )
พลเมือง

14
ฉันอยู่ภายใต้ความประทับใจที่ว่าบริการเป็นแบบซิงเกิลที่คุณใช้โดยการอ้างอิงถึงมัน และโรงงานก็เป็นซิงเกิลตันที่ส่งคืนวัตถุใหม่ทุกครั้ง นั่นคือบริการจะให้ "รถยนต์" หนึ่งคันและทุกสิ่งในโครงการของคุณจะใช้รถคันนี้ ในขณะที่โรงงานจะให้รถใหม่ให้คุณทุกครั้งที่คุณเรียกใช้โรงงาน หนึ่งคือซิงเกิลตันที่ส่งคืนซิงเกิลและอีกอันคือซิงเกิลที่ส่งคืนวัตถุ มีใครอธิบายได้บ้าง การเรียกทุกอย่างที่ซิงเกิลตันไม่ได้ช่วยเพราะมันหมายถึงหลาย ๆ อย่าง
user2483724

380

สำหรับฉันการเปิดเผยเกิดขึ้นเมื่อฉันรู้ว่าพวกเขาทำงานในลักษณะเดียวกัน: โดยการวิ่งบางสิ่งหนึ่งครั้งเก็บค่าที่ได้รับจากนั้นก็ไอค่าที่เก็บไว้เดิมนั้นเมื่ออ้างอิงผ่าน Dependency Injection

บอกว่าเรามี:

app.factory('a', fn);
app.service('b', fn);
app.provider('c', fn);

ความแตกต่างระหว่างสามคือ:

  1. aค่าที่เก็บไว้ของมาจากการทำงานfnในคำอื่น ๆ :fn()
  2. bค่าที่เก็บไว้ของมาจากnewไอเอ็นจีfnในคำอื่น ๆ :new fn()
  3. cค่า 's เก็บไว้มาจากครั้งแรกที่ได้รับตัวอย่างจากnewไอเอ็นจีfnและจากนั้นเรียกใช้$getวิธีการของอินสแตนซ์

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

cache.a = fn()
cache.b = new fn()
cache.c = (new fn()).$get()

นี่คือเหตุผลที่เราใช้thisบริการและกำหนดthis.$getผู้ให้บริการ

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


54
ในที่สุดคำอธิบายที่มีเหตุผล เชิงมุมเป็นบ้าและแย่มากจนเจ็บ
โอซิริส

8
นี่ควรเป็นคำตอบที่ได้รับการยอมรับเพราะจริง ๆ แล้วตอบคำถามของทำไมโรงงานบริการและผู้ให้บริการส่งคืนค่าซิงเกิล คำตอบอื่น ๆ อธิบายถึงความแตกต่างระหว่างโรงงานบริการและผู้ให้บริการ แต่ไม่เคยสัมผัสในแง่มุมเดียว
wmock

3
ฉันชอบสิ่งนี้ ... เมื่อฉันอ่านประโยคพันบรรทัดจากบล็อกเกอร์อื่น ๆ .. ฉันจัดการทำความเข้าใจกับโรงงานเท่านั้น แต่ฉันอ่านสิ่งนี้ ... ฉันเข้าใจทั้งหมด 3.
tsohtan

@osiris ฉันเห็นด้วย ฉันไม่ชอบมัน มันรู้สึกประหลาดมากอย่างใกล้ชิดควบคู่ไปกับมันทำให้ฟันของฉันบด
โทมัส

2
ดังนั้นคุณต้องเตรียมการติดตั้ง $ get เมื่อใช้ผู้ให้บริการ
Victor

95

ตัวอย่างสด

ตัวอย่าง "สวัสดีชาวโลก"

ด้วยfactory/ service/ provider:

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

//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
    this.sayHello = function() {
        return "Hello, World!"
    };
});

//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
    return {
        sayHello: function() {
            return "Hello, World!"
        }
    };
});

//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {
    // In the provider function, you cannot inject any
    // service or factory. This can only be done at the
    // "$get" method.

    this.name = 'Default';

    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!"
            }
        }
    };

    this.setName = function(name) {
        this.name = name;
    };
});

//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});


function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {

    $scope.hellos = [
        helloWorld.sayHello(),
        helloWorldFromFactory.sayHello(),
        helloWorldFromService.sayHello()];
}​

57

นอกจากนี้ยังมีวิธีส่งคืนฟังก์ชันตัวสร้างเพื่อให้คุณสามารถส่งคืนคลาสที่สามารถสร้างได้ใหม่ในโรงงานเช่นนี้

function MyObjectWithParam($rootScope, name) {
  this.$rootScope = $rootScope;
  this.name = name;
}
MyObjectWithParam.prototype.getText = function () {
  return this.name;
};

App.factory('MyObjectWithParam', function ($injector) {
  return function(name) { 
    return $injector.instantiate(MyObjectWithParam,{ name: name });
  };
}); 

ดังนั้นคุณสามารถทำได้ในคอนโทรลเลอร์ซึ่งใช้ MyObjectWithParam:

var obj = new MyObjectWithParam("hello"),

ดูตัวอย่างทั้งหมดได้ที่นี่:
http://plnkr.co/edit/GKnhIN?p=preview

และนี่คือหน้ากลุ่ม Google ที่มีการพูดถึง:
https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/b8hdPskxZXsJ


ฉันมีปัญหากับการลดขนาดโดยใช้ตัวอย่างของคุณ คุณรู้หรือไม่ว่าฉันควรอธิบายสิ่งนี้อย่างไร
Pål

2
ใช่มีสัญกรณ์ที่ย่อสำหรับ Angular มันควรจะเป็นแบบนี้: App.factory('MyObjectWithParam', ['$injector', function ($injector) { return function(name) { return $injector.instantiate(MyObjectWithParam,{ name: name }); }; }]); อ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ที่นี่: docs.angularjs.org/tutorial/step_05
JustGoscha

4
ทำไมคุณต้องการทำเช่นนี้หากคุณสามารถใช้.serviceแทน
flup

ฉันมีความคิดแบบเดียวกัน @flup @justgoscha จะมีผลประโยชน์บางอย่าง ( รับรู้? ) ของการใช้.factoryเมื่อเทียบกับ.service?
xandercoded

5
ผมคิดว่าเพราะบริการที่เป็นเดี่ยว สิ่งที่ฉันสร้างขึ้นที่นี่นั้นเป็นคลาสที่สามารถรับได้ เพื่อให้คุณสามารถมีบางอย่างเช่นโรงงานบริการรถแล้วทำให้new Car('BMW')และnew Car('Ford')และพวกเขาไม่ได้ร่วมตัวแปรเดียวและทุกอย่าง
JustGoscha

51

นี่คือความแตกต่างหลัก:

บริการ

ไวยากรณ์: module.service( 'serviceName', function );

ส่งผลให้เกิด: เมื่อประกาศ SERVICENAME เป็นอาร์กิวเมนต์ฉีดคุณจะมีให้กับอินสแตนซ์ของฟังก์ชันmodule.serviceส่งผ่านไปยัง

การใช้งาน: อาจมีประโยชน์สำหรับการแบ่งปันฟังก์ชั่นยูทิลิตี้ที่มีประโยชน์ในการเรียกใช้โดยการต่อท้าย () เพื่อการอ้างอิงฟังก์ชั่นการฉีด อาจจะทำงานด้วยinjectedArg.call( this )หรือคล้ายกัน

โรงงาน

ไวยากรณ์: module.factory( 'factoryName', function );

ส่งผลให้เกิด: เมื่อประกาศ factoryName เป็นอาร์กิวเมนต์ฉีดคุณจะให้ค่าที่ถูกส่งกลับโดยเรียกอ้างอิงฟังก์ชันmodule.factoryส่งผ่านไปยัง

การใช้งาน: อาจมีประโยชน์สำหรับการส่งคืนฟังก์ชัน'คลาส'ที่สามารถเป็น new'ed เพื่อสร้างอินสแตนซ์

นอกจากนี้ตรวจสอบเอกสาร AngularJSและคำถามที่คล้ายกันใน StackOverflow สับสนเกี่ยวกับการบริการเทียบกับโรงงาน

นี่คือตัวอย่างการใช้บริการและโรงงาน อ่านเพิ่มเติมเกี่ยวกับบริการ AngularJS VS โรงงาน


6
เรื่องนี้ทำให้รู้สึกถึงฉัน โรงงานของเขาคืนค่าพิมพ์เขียวสำหรับการสร้างวัตถุใหม่

27

การเพิ่มคำตอบแรกฉันคิดว่า .service () สำหรับผู้ที่เขียนโค้ดของพวกเขาในแบบเชิงวัตถุมากขึ้น (C # / Java) (ใช้คำหลักนี้และวัตถุสร้างอินสแตนซ์ผ่านฟังก์ชันต้นแบบ / ตัวสร้าง)

Factory เหมาะสำหรับนักพัฒนาที่เขียนโค้ดซึ่งเป็นธรรมชาติมากกว่าในรูปแบบจาวาสคริปต์ / ฟังก์ชั่นการเขียนโค้ด

ดูซอร์สโค้ดของ. บริการและวิธีการ. โรงงานภายใน angular.js - ภายในพวกเขาทั้งหมดวิธีการโทร:

  function provider(name, provider_) {
    if (isFunction(provider_)) {
      provider_ = providerInjector.instantiate(provider_);
    }
    if (!provider_.$get) {
      throw Error('Provider ' + name + ' must define $get factory method.');
    }
    return providerCache[name + providerSuffix] = provider_;
  }

  function factory(name, factoryFn) { \
    return provider(name, { $get: factoryFn }); 
  }

  function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
  }

25

ง่ายมาก:

.service - ฟังก์ชันที่ลงทะเบียนจะถูกเรียกใช้เป็นตัวสร้าง (aka 'newed')

.factory - ฟังก์ชั่นที่ลงทะเบียนจะถูกเรียกใช้เป็นฟังก์ชั่นที่เรียบง่าย

ทั้งสองถูกเรียกใช้ครั้งเดียวส่งผลให้วัตถุเดี่ยวที่ได้รับการฉีดเข้าไปในส่วนประกอบอื่น ๆ ของแอพของคุณ


6
ใช่. อย่าทำให้สิ่งที่ซับซ้อนเกินกว่าที่ควรจะเป็น
flup

20

ผู้ให้บริการทั้งหมดทำงานในลักษณะเดียวกัน วิธีการที่แตกต่างกันservice, factory, providerเพียงแค่ให้คุณประสบความสำเร็จในสิ่งเดียวกันในรหัสน้อย

PS นอกจากนี้ยังมีและvalueconstant

แต่ละกรณีพิเศษลงโซ่เริ่มต้นด้วยproviderและลงท้ายด้วยvalueมีข้อ จำกัด เพิ่ม ดังนั้นในการตัดสินใจระหว่างพวกเขาคุณต้องถามตัวเองว่าให้คุณทำอะไรที่คุณต้องการด้วยรหัสน้อย

นี่คือรูปภาพที่แสดงสิ่งที่ฉันหมายถึง:

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

คุณสามารถดูรายละเอียดและคู่มืออ้างอิงในโพสต์บล็อกฉันได้ภาพนี้จาก:

http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/


มีการกล่าวกันว่าบริการเป็นซิงเกิล แต่ทำไมถึงเป็นซิงเกิลถ้ามีการสร้างอินสแตนซ์ใหม่ทุกครั้งที่ฉันฉีดมัน?
Ankur Marwaha

1
@AnkurMarwaha อินสแตนซ์ใหม่ไม่ได้ถูกสร้างขึ้นในแต่ละครั้งมันสร้างเพียงครั้งเดียวและถูกแคชโดย AngularJS สิ่งนี้เป็นจริงไม่ว่าคุณจะใช้ผู้ให้บริการโรงงานบริการ ฯลฯ คุณสามารถยืนยันการใช้console.log()และการฉีดเข้าไปในคอนโทรลเลอร์หลายตัว
Luis Perez

หลุยส์ความคิดเห็นของคุณขัดแย้งกับคำตอบที่ได้รับการยอมรับตามที่ระบุไว้ - สุดท้ายสิ่งสำคัญคือการตระหนักว่าบริการเชิงมุมทั้งหมดเป็นแอปพลิเคชันเดี่ยว ซึ่งหมายความว่ามีเพียงหนึ่งอินสแตนซ์ของบริการที่กำหนดต่อหัวฉีด
Ankur Marwaha

@AnkurMarwaha บางทีฉันอาจเข้าใจผิดบางอย่าง คุณยกมา "เป็นสิ่งสำคัญที่ต้องตระหนักว่าบริการ Angular ทั้งหมดเป็นแอปพลิเคชันเดี่ยว" - ความจริงที่ว่าพวกเขาเป็นซิงเกิลหมายความว่าพวกเขาจะถูกสร้างขึ้นเพียงครั้งเดียว ซึ่งเป็นสิ่งที่ฉันพูดว่า "อินสแตนซ์ใหม่ไม่ได้ถูกสร้างขึ้นในแต่ละครั้งจะถูกสร้างเพียงครั้งเดียวและแคช ... " คุณช่วยชี้รายละเอียดเพิ่มเติมที่คุณเห็นความขัดแย้งได้หรือไม่?
Luis Perez

1
อาฉันเห็นความสับสน "หัวฉีด" เป็นวัตถุในเชิงมุม มันรับผิดชอบในการทำ "การฉีด" ตัวอย่างเมื่อตัวควบคุมถูกเรียกใช้ครั้งแรก "หัวฉีด" จะดูพารามิเตอร์และฉีดแต่ละอัน มี "หัวฉีด" เดียวเท่านั้นสำหรับแอปทั้งหมดของคุณ เมื่อหัวฉีดสร้างโรงงานหรือบริการเฉพาะมันจะเก็บอินสแตนซ์ไว้และนำกลับมาใช้ใหม่ - ดังนั้นจึงเป็นซิงเกิล ดังนั้นจึงมีเพียงหนึ่งหัวฉีดต่อแอปหนึ่งอินสแตนซ์เดียวของบริการที่กำหนดต่อหัวฉีด การใช้งานเชิงมุมส่วนใหญ่มีเพียงหนึ่งแอปจึงหนึ่งหัวฉีดจึงหนึ่งตัวอย่างของบริการใด ๆ ควบคุม ฯลฯ
หลุยส์เปเรซ

13

นี่คือตัวอย่างเพิ่มเติมของบริการและโรงงานซึ่งอาจเป็นประโยชน์ในการเห็นความแตกต่างระหว่างพวกเขา โดยพื้นฐานแล้วบริการได้เรียกว่า "ใหม่ ... " บริการนี้มีการยกตัวอย่างแล้ว โรงงานจะไม่สร้างอินสแตนซ์โดยอัตโนมัติ

ตัวอย่างพื้นฐาน

ส่งคืนคลาสอ็อบเจ็กต์ซึ่งมีเมธอดเดียว

นี่คือบริการที่มีวิธีการเดียว:

angular.service('Hello', function () {
  this.sayHello = function () { /* ... */ };
});

นี่คือโรงงานที่คืนค่าออบเจคด้วยเมธอด:

angular.factory('ClassFactory', function () {
  return {
    sayHello: function () { /* ... */ }
  };
});

ส่งคืนค่า

โรงงานที่ส่งคืนรายการหมายเลข:

angular.factory('NumberListFactory', function () {
  return [1, 2, 3, 4, 5];
});

console.log(NumberListFactory);

บริการที่ส่งคืนรายการหมายเลข:

angular.service('NumberLister', function () {
  this.numbers = [1, 2, 3, 4, 5];
});

console.log(NumberLister.numbers);

เอาต์พุตในทั้งสองกรณีจะเหมือนกันคือรายการของตัวเลข

ตัวอย่างขั้นสูง

ตัวแปร "คลาส" โดยใช้โรงงาน

ในตัวอย่างนี้เรากำหนด CounterFactory มันเพิ่มหรือลดเคาน์เตอร์และคุณสามารถรับจำนวนปัจจุบันหรือรับจำนวนวัตถุ CounterFactory ที่ถูกสร้าง:

angular.factory('CounterFactory', function () {
  var number_of_counter_factories = 0; // class variable

  return function () {
    var count = 0; // instance variable
    number_of_counter_factories += 1; // increment the class variable

    // this method accesses the class variable
    this.getNumberOfCounterFactories = function () {
      return number_of_counter_factories;
    };

    this.inc = function () {
      count += 1;
    };
    this.dec = function () {
      count -= 1;
    };
    this.getCount = function () {
      return count;
    };
  }

})

เราใช้CounterFactoryเพื่อสร้างหลายเคาน์เตอร์ เราสามารถเข้าถึงตัวแปรคลาสเพื่อดูจำนวนตัวนับที่สร้างขึ้น:

var people_counter;
var places_counter;

people_counter = new CounterFactory();
console.log('people', people_counter.getCount());
people_counter.inc();
console.log('people', people_counter.getCount());

console.log('counters', people_counter.getNumberOfCounterFactories());

places_counter = new CounterFactory();
console.log('places', places_counter.getCount());

console.log('counters', people_counter.getNumberOfCounterFactories());
console.log('counters', places_counter.getNumberOfCounterFactories());

ผลลัพธ์ของรหัสนี้คือ:

people 0
people 1
counters 1
places 0
counters 2
counters 2

มันเป็นตัวอย่างที่มีประโยชน์ number_of_counter_factories เหมือน meta atrribute ของคลาส CounterFactory ใช่มั้ยฉันเข้าใจว่าตัวอย่างนี้สามารถจำลองได้ในบริการ
geoom

ตัวอย่างที่มีประโยชน์! นี่หมายความว่าโดยทั่วไปแล้วในโรงงานคุณสามารถมีชั้นของนามธรรมที่จะไม่ได้รับบริการ จะมีการส่งคืนอินสแตนซ์ใหม่ของมันเมื่อใดก็ตามที่มีการใช้ 'ใหม่' ตัวแปรใด ๆ ที่ไม่ได้ประกาศไว้ในบล็อกการส่งคืนจะเป็นแบบซิงเกิล ฉันทำให้ถูกต้องหรือไม่
Swanidhi

@Swanidhi โดยทั่วไปใช่คุณสามารถประกาศตัวแปรที่เป็นซิงเกิลตันในโรงงาน นั่นเป็นเหตุผลที่ฉันเรียกพวกเขาว่า "คลาส" ตัวแปร

13

“ โรงงาน” และ“ บริการ” เป็นวิธีที่แตกต่างกันในการทำ DI (การพึ่งพาการฉีด) ในเชิงมุม

ดังนั้นเมื่อเรากำหนด DI โดยใช้“ บริการ” ดังที่แสดงในรหัสด้านล่าง สิ่งนี้จะสร้างอินสแตนซ์ GLOBAL ใหม่ของวัตถุ“ Logger” และแทรกลงในฟังก์ชัน

app.service("Logger", Logger); // Injects a global object

เมื่อคุณกำหนด DI โดยใช้“ โรงงาน” มันจะไม่สร้างอินสแตนซ์ มันเพิ่งผ่านวิธีการและต่อมาผู้บริโภคภายในจะต้องโทรไปยังโรงงานสำหรับอินสแตนซ์ของวัตถุ

app.factory("Customerfactory", CreateCustomer);

ด้านล่างเป็นภาพง่าย ๆ ซึ่งแสดงให้เห็นว่ากระบวนการ DI สำหรับ "บริการ" แตกต่างจาก "โรงงาน" อย่างไร

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

ควรใช้โรงงานเมื่อเราต้องการสร้างวัตถุประเภทต่าง ๆ ขึ้นอยู่กับสถานการณ์ ตัวอย่างขึ้นอยู่กับสถานการณ์ที่เราต้องการสร้างวัตถุ "ลูกค้า" แบบง่ายหรือ "ลูกค้า" ด้วยวัตถุ "ที่อยู่" หรือ "ลูกค้า" ด้วยวัตถุ "โทรศัพท์" นี่คือคำอธิบายโดยละเอียดของย่อหน้านี้

ควรใช้บริการเมื่อเรามียูทิลิตี้หรือฟังก์ชั่นที่ใช้ร่วมกันที่จะฉีดเช่นยูทิลิตี้, Logger, จัดการข้อผิดพลาด ฯลฯ


ทุกคำตอบที่ฉันเห็นในคำถามนี้และคำอื่น ๆ ที่คล้ายกันกำลังระบุความแตกต่างในกลไกและไวยากรณ์ คำตอบนี้ให้เหตุผลที่แท้จริงว่าทำไมคุณถึงเลือกหนึ่ง มันเป็นเรื่องของความหมายและดูที่ชื่อบริการหรือโรงงานสื่อสารวัตถุประสงค์และวิธีการใช้งานของพวกเขา
Joe Mayo

8

ลักษณะบริการ : ( น่าจะง่ายที่สุด ) ส่งคืนฟังก์ชันจริง: มีประโยชน์สำหรับการแบ่งปันฟังก์ชั่นยูทิลิตี้ที่มีประโยชน์ในการเรียกใช้โดยการต่อท้าย () ไปยังการอ้างอิงฟังก์ชันฉีด

บริการใน AngularJS เป็นวัตถุ JavaScript เดี่ยวซึ่งมีชุดของฟังก์ชั่น

var myModule = angular.module("myModule", []);

myModule.value  ("myValue"  , "12345");

function MyService(myValue) {
    this.doIt = function() {
        console.log("done: " + myValue;
    }
}

myModule.service("myService", MyService);
myModule.controller("MyController", function($scope, myService) {

    myService.doIt();

});

สไตล์โรงงาน : ( เกี่ยวข้องมากขึ้น แต่ซับซ้อนยิ่งขึ้น ) ส่งคืนค่าส่งคืนของฟังก์ชัน: ยกตัวอย่างวัตถุเช่น Object ใหม่ () ใน java

Factory เป็นฟังก์ชั่นที่สร้างคุณค่า เมื่อบริการผู้ควบคุม ฯลฯ ต้องการค่าที่ฉีดจากโรงงานโรงงานจะสร้างมูลค่าตามต้องการ เมื่อสร้างแล้วค่าจะถูกนำมาใช้ซ้ำสำหรับบริการทั้งหมดตัวควบคุมและอื่น ๆ ซึ่งจำเป็นต้องมีการฉีด

var myModule = angular.module("myModule", []);

myModule.value("numberValue", 999);

myModule.factory("myFactory", function(numberValue) {
    return "a value: " + numberValue;
})  
myModule.controller("MyController", function($scope, myFactory) {

    console.log(myFactory);

});

รูปแบบของผู้ให้บริการ : ( เวอร์ชั่นเต็มเป่า, กำหนดรูปแบบได้ ) ส่งคืนเอาต์พุตของฟังก์ชัน $ get ของฟังก์ชัน: กำหนดค่าได้

ผู้ให้บริการใน AngularJS เป็นรูปแบบโรงงานที่ยืดหยุ่นที่สุดที่คุณสามารถสร้างได้ คุณลงทะเบียนผู้ให้บริการด้วยโมดูลเช่นเดียวกับที่คุณทำกับบริการหรือโรงงานยกเว้นคุณใช้ฟังก์ชัน Provider () แทน

var myModule = angular.module("myModule", []);

myModule.provider("mySecondService", function() {
    var provider = {};
    var config   = { configParam : "default" };

    provider.doConfig = function(configParam) {
        config.configParam = configParam;
    }

    provider.$get = function() {
        var service = {};

        service.doService = function() {
            console.log("mySecondService: " + config.configParam);
        }

        return service;
    }

    return provider;
});

myModule.config( function( mySecondServiceProvider ) {
    mySecondServiceProvider.doConfig("new config param");
});

myModule.controller("MyController", function($scope, mySecondService) {

    $scope.whenButtonClicked = function() {
        mySecondService.doIt();
    }

});

src jenkov

<!DOCTYPE html>
    <html ng-app="app">
    <head>
    	<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
    	<meta charset=utf-8 />
    	<title>JS Bin</title>
    </head>
    <body ng-controller="MyCtrl">
    	{{serviceOutput}}
    	<br/><br/>
    	{{factoryOutput}}
    	<br/><br/>
    	{{providerOutput}}
    
    	<script>
    
    		var app = angular.module( 'app', [] );
    
    		var MyFunc = function() {
    
    			this.name = "default name";
    
    			this.$get = function() {
    				this.name = "new name"
    				return "Hello from MyFunc.$get(). this.name = " + this.name;
    			};
    
    			return "Hello from MyFunc(). this.name = " + this.name;
    		};
    
    		// returns the actual function
    		app.service( 'myService', MyFunc );
    
    		// returns the function's return value
    		app.factory( 'myFactory', MyFunc );
    
    		// returns the output of the function's $get function
    		app.provider( 'myProv', MyFunc );
    
    		function MyCtrl( $scope, myService, myFactory, myProv ) {
    
    			$scope.serviceOutput = "myService = " + myService;
    			$scope.factoryOutput = "myFactory = " + myFactory;
    			$scope.providerOutput = "myProvider = " + myProv;
    
    		}
    
    	</script>
    
    </body>
    </html>

jsbin

<!DOCTYPE html>
<html ng-app="myApp">
<head>
	<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
	<meta charset=utf-8 />
	<title>JS Bin</title>
</head>
<body>
<div ng-controller="MyCtrl">
    {{hellos}}
</div>
	<script>

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

//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
    this.sayHello = function() {
        return "Hello, World!"
    };
});

//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
    return {
        sayHello: function() {
            return "Hello, World!"
        }
    };
});
    
//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {

    this.name = 'Default';

    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!"
            }
        }
    };

    this.setName = function(name) {
        this.name = name;
    };
});

//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});
        

function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {
    
    $scope.hellos = [
        helloWorld.sayHello(),
        helloWorldFromFactory.sayHello(),
        helloWorldFromService.sayHello()];
}
	</script>

</body>
</html>

jsfiddle


2

ความแตกต่างพื้นฐานคือผู้ให้บริการอนุญาตให้ตั้งค่าดั้งเดิม (ไม่ใช่วัตถุ), อาเรย์หรือฟังก์ชันการเรียกกลับเข้าไปในตัวแปรที่ประกาศจากโรงงานและดังนั้นหากส่งคืนวัตถุจะต้องมีการประกาศและส่งคืนอย่างชัดเจน

ในทางกลับกันบริการสามารถใช้เพื่อตั้งค่าบริการที่ประกาศตัวแปรเป็นวัตถุเท่านั้นดังนั้นเราสามารถหลีกเลี่ยงการสร้างและส่งคืนวัตถุได้อย่างชัดเจนในขณะที่ในทางกลับกันก็อนุญาตให้ใช้คำหลักนี้ได้

หรือกล่าวโดยย่อว่า " ผู้ให้บริการเป็นรูปแบบทั่วไปมากขึ้นในขณะที่บริการนั้น จำกัด อยู่ที่วัตถุเท่านั้น"


2

นี่คือวิธีที่ฉันเข้าใจความแตกต่างระหว่างพวกเขาในแง่ของรูปแบบการออกแบบ:

บริการ : คืนประเภทที่จะถูกสร้างใหม่เพื่อสร้างวัตถุประเภทนั้น หากเปรียบเทียบ Java จะใช้บริการส่งกลับนิยามชั้น Java

โรงงาน : ส่งคืนวัตถุคอนกรีตที่สามารถใช้งานได้ทันที ใน Java คล้ายคลึงโรงงานส่งกลับวัตถุ Java

ส่วนที่ทำให้ผู้คนสับสน (รวมถึงตัวเอง) คือเมื่อคุณฉีด Service หรือ Factory ในรหัสของคุณพวกเขาสามารถใช้วิธีเดียวกันสิ่งที่คุณได้รับในรหัสของคุณในทั้งสองกรณีเป็นวัตถุที่คุณสามารถเรียกใช้ได้ทันที ซึ่งหมายความว่าในกรณีของการบริการการเรียกมุม "ใหม่" ในการประกาศการบริการในนามของคุณ ฉันคิดว่านี่เป็นแนวคิดที่ซับซ้อน


1

นี่จะเป็นคำตอบที่สั้นและดีที่สุดสำหรับการทำความเข้าใจ Service Vs Factory Vs Provider

ที่มา : https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/HuZsOsMvKv4J

นี่คือสิ่งที่เบ็นพูดพร้อมกับตัวอย่าง http://jsbin.com/ohamub/1/edit?html

"มีความคิดเห็นในรหัสที่แสดงถึงความแตกต่างหลัก แต่ฉันจะขยายพวกเขาที่นี่เล็กน้อยตามที่ทราบฉันเพิ่งได้รับรอบนี้ดังนั้นถ้าฉันพูดอะไรผิดโปรดแจ้งให้เราทราบ

บริการ

ไวยากรณ์ : module.service ('serviceName', ฟังก์ชัน);

ผลลัพธ์ : เมื่อประกาศ serviceName เป็นอาร์กิวเมนต์แบบฉีดคุณจะได้รับการอ้างอิงฟังก์ชันจริงที่ส่งผ่านไปยัง module.service

การใช้งาน : อาจมีประโยชน์สำหรับการแบ่งปันฟังก์ชั่นยูทิลิตี้ที่มีประโยชน์ในการเรียกใช้โดยการต่อท้าย () เพื่อการอ้างอิงฟังก์ชั่นการฉีด สามารถเรียกใช้กับ injectedArg.call (นี่) หรือคล้ายกันได้

โรงงาน

ไวยากรณ์ : module.factory ('factoryName', ฟังก์ชัน);

ผลลัพธ์ : เมื่อประกาศ factoryName เป็นอาร์กิวเมนต์แบบฉีดคุณจะได้รับค่าที่ส่งคืนโดยเรียกใช้การอ้างอิงฟังก์ชันที่ส่งผ่านไปยัง module.factory

การใช้งาน : อาจมีประโยชน์สำหรับการส่งคืนฟังก์ชัน 'คลาส' ที่สามารถเป็น new'ed เพื่อสร้างอินสแตนซ์

ผู้ให้บริการ

ไวยากรณ์ : module.provider ('providerName', ฟังก์ชัน);

ผลลัพธ์ : เมื่อประกาศ providerName เป็นอาร์กิวเมนต์แบบฉีดคุณจะได้รับค่าที่ส่งคืนโดยเรียกใช้เมธอด $ get ของการอ้างอิงฟังก์ชันที่ส่งผ่านไปยัง module.provider

การใช้งาน : อาจมีประโยชน์สำหรับการส่งคืนฟังก์ชัน 'คลาส' ที่สามารถเป็น new'ed เพื่อสร้างอินสแตนซ์ แต่ต้องใช้การกำหนดค่าบางอย่างก่อนที่จะถูกส่ง อาจมีประโยชน์สำหรับคลาสที่นำมาใช้ใหม่ในโครงการหรือไม่ ยังคงมีหมอกในนี้ "เบ็น


1

ฉันสับสนในขณะนี้และฉันพยายามอย่างดีที่สุดเพื่อให้คำอธิบายง่ายๆที่นี่ หวังว่านี่จะช่วยได้!

angular .factoryและangular .serviceทั้งสองถูกใช้เพื่อเริ่มต้นบริการและทำงานในลักษณะเดียวกัน

ข้อแตกต่างคือวิธีที่คุณต้องการเริ่มต้นบริการของคุณ

ทั้งคู่เป็นซิงเกิลตัน


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


โรงงาน

app.factory ( <service name>, <function with a return value>)

หากคุณต้องการเริ่มต้นบริการของคุณจากฟังก์ชันที่คุณมีโดยมีค่าส่งคืนคุณต้องใช้factoryวิธีนี้

เช่น

function myService() {
  //return what you want
  var service = {
    myfunc: function (param) { /* do stuff */ }
  }
  return service;
}

app.factory('myService', myService);

เมื่อฉีดบริการนี้ (เช่นไปยังคอนโทรลเลอร์ของคุณ):

  • Angular จะเรียกใช้ฟังก์ชันที่คุณได้รับ (เป็นmyService()) เพื่อส่งคืนวัตถุ
  • Singleton - เรียกเพียงครั้งเดียวจัดเก็บและส่งผ่านวัตถุเดียวกัน


บริการ

app.service ( <service name>, <constructor function>)

หากคุณต้องการเริ่มต้นบริการของคุณจากฟังก์ชั่น Constructor (โดยใช้thisคำสำคัญ) คุณต้องใช้serviceวิธีนี้

เช่น

function myService() {
  this.myfunc: function (param) { /* do stuff */ }
}

app.service('myService', myService);

เมื่อฉีดบริการนี้ (เช่นไปยังคอนโทรลเลอร์ของคุณ):

  • Angular จะnewรับฟังก์ชั่นที่คุณให้ไว้ (as new myService()) เพื่อส่งคืนวัตถุ
  • Singleton - เรียกเพียงครั้งเดียวจัดเก็บและส่งผ่านวัตถุเดียวกัน


หมายเหตุ: หากคุณใช้factoryกับ<constructor function>หรือserviceกับ<function with a return value>มันจะไม่ทำงาน


ตัวอย่าง - ตัวอย่าง


1

นี่คือสิ่งที่ช่วยให้ฉันเข้าใจความแตกต่างขอบคุณโพสต์บล็อกโดย Pascal Precht

บริการเป็นวิธีการในโมดูลที่ใช้ชื่อและฟังก์ชั่นที่กำหนดบริการ คุณสามารถฉีดและใช้บริการนั้นในส่วนประกอบอื่น ๆ เช่นตัวควบคุมคำสั่งและตัวกรอง โรงงานเป็นวิธีการในโมดูลและยังใช้ชื่อและฟังก์ชั่นที่กำหนดโรงงาน นอกจากนี้เรายังสามารถฉีดและใช้วิธีเดียวกับที่เราทำกับบริการ

วัตถุที่สร้างด้วยการใช้ใหม่จะใช้ค่าของคุณสมบัติต้นแบบของฟังก์ชันคอนสตรัคเตอร์ของพวกเขาเป็นต้นแบบดังนั้นฉันจึงพบรหัส Angular ที่เรียกว่า Object.create () ซึ่งฉันเชื่อว่าเป็นฟังก์ชันตัวสร้างบริการเมื่อได้รับอินสแตนซ์ อย่างไรก็ตามฟังก์ชั่นจากโรงงานเป็นเพียงฟังก์ชั่นที่ได้รับการเรียกซึ่งเป็นสาเหตุที่เราต้องส่งคืนตัวอักษรวัตถุสำหรับโรงงาน

นี่คือรหัส 1.5 เชิงมุมที่ฉันพบสำหรับโรงงาน:

var needsRecurse = false;
    var destination = copyType(source);

    if (destination === undefined) {
      destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
      needsRecurse = true;
    }

ข้อมูลโค้ดเชิงมุมสำหรับฟังก์ชั่น factory ():

 function factory(name, factoryFn, enforce) {
    return provider(name, {
      $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
    });
  }

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

นี่คือรหัส 1.5 เชิงมุมสำหรับการให้บริการ

function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
  }

ปรากฎว่าเมื่อเราเรียกบริการ () มันจะเรียกโรงงาน () จริง ๆ ! อย่างไรก็ตามมันไม่เพียงส่งผ่านฟังก์ชั่นตัวสร้างบริการของเราไปยังโรงงานตามที่เป็นอยู่ นอกจากนี้ยังผ่านฟังก์ชั่นที่ถามหัวฉีดเพื่อสร้างอินสแตนซ์วัตถุโดยตัวสร้างที่กำหนด

กล่าวอีกนัยหนึ่งถ้าเราฉีด MyService ที่ไหนสักแห่งสิ่งที่เกิดขึ้นในรหัสคือ:

MyServiceProvider.$get(); // return the instance of the service

เพื่อเรียกคืนอีกครั้งบริการจะเรียกโรงงานซึ่งเป็นวิธีการ $ get () ของผู้ให้บริการที่เกี่ยวข้อง ยิ่งไปกว่านั้น $ injector.instantiate () เป็นวิธีการที่เรียก Object.create () ในท้ายที่สุดด้วยฟังก์ชั่นคอนสตรัค นั่นเป็นเหตุผลที่เราใช้ "สิ่งนี้" ในบริการ

สำหรับ ES5 นั้นไม่สำคัญว่าเราจะใช้อะไร: บริการ () หรือโรงงาน () มันเป็นโรงงานที่ถูกเรียกเสมอซึ่งสร้างผู้ให้บริการสำหรับบริการของเรา

คุณสามารถทำสิ่งเดียวกันกับบริการได้เช่นกัน บริการเป็นฟังก์ชั่นคอนสตรัคเตอร์ที่ไม่ได้ป้องกันเราจากการคืนค่าตัวอักษรวัตถุ ดังนั้นเราสามารถใช้รหัสบริการของเราและเขียนมันในลักษณะที่มันทำสิ่งเดียวกันกับโรงงานของเราหรือในคำอื่น ๆ คุณสามารถเขียนบริการเป็นโรงงานเพื่อส่งคืนวัตถุ

ทำไมคนส่วนใหญ่แนะนำให้ใช้โรงงานมากกว่าบริการ นี่คือคำตอบที่ดีที่สุดที่ฉันเคยเห็นซึ่งมาจากหนังสือของ Pawel Kozlowski: Mastering Web Application Development กับ AngularJS

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


1
  • เมื่อสร้างโรงงานคุณจะสร้างวัตถุภายในโรงงานและส่งคืนวัตถุนั้น
  • ด้วยบริการที่คุณเพิ่งมีฟังก์ชั่นมาตรฐานที่ใช้ thisคำหลักเพื่อกำหนดฟังก์ชั่น
  • ด้วยผู้ให้บริการจะมีการ$getกำหนดและสามารถใช้เพื่อรับวัตถุที่ส่งคืนข้อมูล

1

มีสามวิธีในการจัดการตรรกะทางธุรกิจใน AngularJS: ( ได้รับแรงบันดาลใจจากหลักสูตร Coursera AngularJS ของยาคอฟ ) ซึ่ง ได้แก่ :

  1. บริการ
  2. โรงงาน
  3. ผู้ให้บริการ

ที่นี่เราจะพูดคุยเกี่ยวกับService vs Factory เท่านั้น

บริการ :

ไวยากรณ์:

app.js

 var app = angular.module('ServiceExample',[]);
 var serviceExampleController =
              app.controller('ServiceExampleController', ServiceExampleController);
 var serviceExample = app.service('NameOfTheService', NameOfTheService);

 ServiceExampleController.$inject = ['NameOfTheService'] //very important as this protects from minification of js files

function ServiceExampleController(NameOfTheService){
     serviceExampleController = this;
     serviceExampleController.data = NameOfTheService.getSomeData();
 }

function NameOfTheService(){
     nameOfTheService = this;
     nameOfTheService.data = "Some Data";
     nameOfTheService.getSomeData = function(){
           return nameOfTheService.data;
     }     
}

index.html

<div ng-controller = "ServiceExampleController as serviceExample">
   {{serviceExample.data}}
</div>

คุณสมบัติหลักของบริการ:

  1. Lazilyอินสแตนซ์: หากบริการไม่ถูกฉีดจะไม่มีการสร้างอินสแตนซ์ ดังนั้นในการใช้มันคุณจะต้องฉีดมันเข้าไปในโมดูล

  2. ซิงเกิลตัน : ถ้ามันถูกส่งไปยังหลาย ๆ โมดูลทั้งหมดจะสามารถเข้าถึงอินสแตนซ์เฉพาะหนึ่งเดียวได้ นั่นคือเหตุผลที่สะดวกในการใช้ข้อมูลร่วมกันระหว่างตัวควบคุมที่แตกต่างกัน

โรงงาน

ทีนี้มาพูดถึงโรงงานใน AngularJS กัน

ก่อนอื่นเรามาดูที่ไวยากรณ์ :

app.js :

var app = angular.module('FactoryExample',[]);
var factoryController = app.controller('FactoryController', FactoryController);
var factoryExampleOne = app.factory('NameOfTheFactoryOne', NameOfTheFactoryOne);
var factoryExampleTwo = app.factory('NameOfTheFactoryTwo', NameOfTheFactoryTwo);

//first implementation where it returns a function
function NameOfTheFactoryOne(){
   var factory = function(){
      return new SomeService();
    }
   return factory;
}

//second implementation where an object literal would be returned
function NameOfTheFactoryTwo(){
   var factory = {
      getSomeService : function(){
          return new SomeService();
       }
    };
   return factory;
}

ตอนนี้ใช้สองข้างต้นในตัวควบคุม:

 var factoryOne = NameOfTheFactoryOne() //since it returns a function
 factoryOne.someMethod();

 var factoryTwo = NameOfTheFactoryTwo.getSomeService(); //accessing the object
 factoryTwo.someMethod();

คุณสมบัติของโรงงาน:

  1. ประเภทของบริการนี้เป็นไปตามรูปแบบการออกแบบโรงงาน โรงงานสามารถถือเป็นศูนย์กลางที่สร้างวัตถุหรือวิธีการใหม่

  2. สิ่งนี้ไม่เพียงผลิตซิงเกิลตันเท่านั้น แต่ยังรวมถึงบริการที่ปรับแต่งได้ด้วย

  3. .service()วิธีการเป็นโรงงานที่มักจะผลิตชนิดเดียวกันในการให้บริการซึ่งเป็นซิงเกิล ไม่มีวิธีง่ายๆในการกำหนดค่าพฤติกรรมของมัน ว่า.service()วิธีการที่มักจะใช้เป็นทางลัดสำหรับบางสิ่งบางอย่างที่ไม่จำเป็นต้องใด ๆ การกำหนดค่าใด ๆ


1

สำหรับคำอธิบายสั้นและง่ายดูhttps://stackoverflow.com/a/26924234/5811973

สำหรับคำอธิบายรายละเอียดดูhttps://stackoverflow.com/a/15666049/5811973

รวมทั้งจากเอกสารประกอบของ angularJs: ป้อนคำอธิบายรูปภาพที่นี่


0

คุณสามารถเข้าใจความแตกต่างด้วยการเปรียบเทียบนี้ - พิจารณาความแตกต่างระหว่างฟังก์ชั่นปกติที่จะคืนค่าบางส่วนและฟังก์ชั่นคอนสตรัคเตอร์ที่จะได้รับอินสแตนซ์โดยใช้คำหลักใหม่ดังนั้นการสร้างโรงงานก็คล้ายกัน วัตถุ) ในขณะที่การสร้างบริการก็เหมือนกับการสร้างฟังก์ชั่นคอนสตรัคเตอร์ (คลาส OO) ซึ่งเราสามารถสร้างอินสแตนซ์โดยใช้คำหลักใหม่ สิ่งเดียวที่ควรสังเกตคือที่นี่คือเมื่อเราใช้วิธีการบริการเพื่อสร้างบริการมันจะสร้างตัวอย่างของมันโดยอัตโนมัติโดยใช้กลไกการฉีดพึ่งพาที่สนับสนุนโดย AngularJS

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