Đối với người mới bắt đầu, ai đó có thể giải thích rõ ràng sự khác biệt giữa Dịch vụ, Nhà máy và Nhà cung cấp trong AngularJS không?


Câu trả lời 1:

AngularJS: Sự khác biệt giữa Dịch vụ so với Nhà cung cấp so với Nhà máy

Nếu bạn đang tìm kiếm điều này có lẽ bởi vì bạn đang cố gắng tìm ra cái nào là phù hợp với bạn để sử dụng. Hoặc bởi vì bạn đã bắt gặp ba người họ và đang cố xác định sự khác biệt bởi vì họ có vẻ giống nhau.

Nếu bạn nghĩ rằng chúng giống nhau - bạn đúng. Chúng rất giống nhau. Trong thực tế, tất cả chúng đều giống nhau.

Họ đều là nhà cung cấp. Nhà máy và dịch vụ chỉ là trường hợp đặc biệt của nhà cung cấp, nhưng bạn có thể hoàn thành mọi thứ bạn muốn chỉ bằng nhà cung cấp. Tôi sẽ cho bạn thấy.

Nhà cung cấp

Chúng tôi sẽ tạo một nhà cung cấp trả về một giá trị và chỉ cần hiển thị giá trị đó, bạn sẽ làm điều này:

var mod = angular.module ("MyModule", []); mod.provider ("myProvider", function () {this. $ get = function () {return "Giá trị của tôi";};}); mod.contler ("MyContoder", function (myProvider) {console.log ("MyControll - myProvider:" + myProvider);}); TIÊU THỤ ĐẦU RA MyContoder - myProvider: My Value

Một ví dụ tương tác làm việc có thể được tìm thấy tại: JS Fiddle.

Ở đó, do đó, một nhà cung cấp dịch vụ trực tuyến tại trung tâm, hãy để bạn cung cấp một giá trị. Giá trị đó có thể là bất cứ điều gì. Trong trường hợp này, đó là một chuỗi có giá trị của Giá trị của tôi Giá trị nhưng nó có thể dễ dàng là một hàm hoặc một đối tượng.

Lưu ý trong các mẫu mã khác tôi sẽ loại trừ thẻ và định nghĩa của mod cho mục đích giữ đoạn trích đoạn mã ngắn và đi vào điểm chính.

Angular chỉ nhận được giá trị một lần - bao giờ hết

Lưu ý rằng chỉ có góc nhìn nhận được giá trị một lần, bất kể nhà cung cấp được tiêm bao nhiêu lần. Điều đó có nghĩa là nó chỉ gọi $ get () một lần, lưu trữ giá trị được cung cấp bởi $ get () và cung cấp cho bạn cùng một giá trị được lưu trữ mỗi lần.

Để cho bạn thấy ý tôi là tôi sẽ tạo một bộ điều khiển khác và tiêm lại nhà cung cấp với câu lệnh console để bạn có thể thấy những gì đang xảy ra.

mod.provider ("myProvider", function () {this. $ get = function () {console.log ("MyProviderFunction. $ get () được gọi."); // THÊM dòng này trả về "Giá trị của tôi";}; }); mod.contler ("MyContoder", function (myProvider) {console.log ("MyControll - myProvider:" + myProvider);}); mod.contler ("MyControll2", function (myProvider) {// THÊM bộ điều khiển này console.log ("MyControll2 - myProvider:" + myProvider);}); TIÊU THỤ ĐẦU RA MyProviderF rối. $ Get () được gọi. MyControll - myProvider: My Value MyControll2 - myProvider: My Value

Mở trong Fiddle JS

Như bạn có thể thấy hàm $ get () chỉ được gọi một lần.

Lưu ý rằng chúng tôi đã viết một loạt mã cho nhà cung cấp chỉ với mục đích tạo ra một phương thức gọi là $ get (). Tại sao không thay vì cung cấp cho một chức năng góc xác định chức năng khác, tại sao không chỉ cung cấp cho nó chức năng mà chúng tôi muốn chạy trực tiếp thay thế? Vâng, bạn có thể, đó là những gì Angular gọi là một nhà máy.

Nhà máy

Với một nhà máy, bạn chỉ cần cung cấp thân hàm cho phương thức $ get và Angular làm phần còn lại. Dưới đây là những gì mã mới trông như thế nào, vì bạn sẽ thấy nó hoạt động giống hệt nhau.

mod.factory ("myProvider", function () {// THANG ĐỔI nhà cung cấp "đến nhà máy" console.log ("Hàm nhà máy được gọi."); trả về "Giá trị của tôi";}); mod.contler ("MyContoder", function (myProvider) {console.log ("MyControll - myProvider:" + myProvider);}); mod.contler ("MyControll2", function (myProvider) {console.log ("MyControll2 - myProvider:" + myProvider);}); TIÊU THỤ ĐẦU RA Chức năng nhà máy được gọi là. MyControll - myProvider: My Value MyControll2 - myProvider: My Value

Mở trong Fiddle JS

Bây giờ bạn có thể tự hỏi tại sao bạn sẽ sử dụng một nhà cung cấp nếu bạn có thể hoàn thành điều tương tự với một nhà máy có ít mã hơn. Có một vài lý do và tôi sẽ đi vào vấn đề đó sau, ngay bây giờ tôi muốn giữ đúng với tiêu đề của bài đăng này và giải quyết sự khác biệt giữa hai (nhà cung cấp và nhà máy) và một dịch vụ.

Cho đến nay chúng ta đã trả về một giá trị chuỗi đơn giản, nhưng trong thực tế, những gì chúng ta có thể muốn trả lại hầu hết thời gian là một đối tượng. Chà, điều đó sẽ không thay đổi ví dụ của chúng ta rất nhiều, chúng ta có thể dễ dàng trao đổi chuỗi chúng ta đang quay lại với một đối tượng thay thế.

Ví dụ, hãy làm điều đó bằng cách trả về một đối tượng có chứa hàm gọi là getValue (). Bây giờ có một số cách bạn có thể tạo một đối tượng trong JavaScript, chúng tôi sẽ sử dụng cách tiếp cận của đối tượng xây dựng đối tượng, nơi chúng tôi tạo một hàm tạo ra một đối tượng có các thuộc tính và hàm và sử dụng từ khóa mới để khởi tạo nó.

function MyObject () {// THÊM hàm tạo đối tượng của chúng tôi this.getValue = function () {return "Giá trị của tôi"; }; } mod.factory ("myProvider", function () {console.log ("Hàm nhà máy được gọi."); trả về MyObject (); // TẠO một thể hiện của đối tượng của chúng tôi}); mod.contler ("MyContoder", function (myProvider) {console.log ("MyControll - myProvider:" + myProvider.getValue ()); // THAY ĐỔI để gọi getValue ()}); mod.contler ("MyControll2", function (myProvider) {console.log ("MyControll2 - myProvider:" + myProvider.getValue ()); // THAY ĐỔI để gọi getValue ()}); TIÊU THỤ ĐẦU RA Chức năng nhà máy được gọi là. MyControll - myProvider: My Value MyControll2 - myProvider: My Value

Mở trong Fiddle JS

Bây giờ tôi muốn thực hiện một điều chỉnh nhỏ cho việc này vì nó sẽ dẫn độc đáo vào khái niệm tiếp theo. Trong ví dụ của chúng tôi, chúng tôi tạo ra hàm My đối tượng xây dựng đối tượng MyObject (), nhưng vì chúng tôi chỉ khởi tạo nó ở một nơi nên chúng tôi có thể sử dụng một hàm ẩn danh thay thế.

Đây là một tinh chỉnh rất nhỏ. Thay vì điều này:

hàm MyObject () {this.getValue = function () {return "Giá trị của tôi"; }; } mod.factory ("myProvider", function () {console.log ("Hàm nhà máy được gọi."); trả về MyObject ();});

Chúng tôi làm điều này:

mod.factory ("myProvider", function () {console.log ("Hàm nhà máy được gọi."); trả về hàm mới () {// TẠO hàm tạo đối tượng của chúng tôi this.getValue = function () {return "Giá trị của tôi"; };};});

Vì vậy, toàn bộ bây giờ trông như thế này:

mod.factory ("myProvider", function () {console.log ("Hàm nhà máy được gọi."); trả về hàm mới () {// TẠO hàm tạo đối tượng của chúng tôi this.getValue = function () {return "Giá trị của tôi"; };};}); mod.contler ("MyContoder", function (myProvider) {console.log ("MyControll - myProvider:" + myProvider.getValue ());}); mod.contler ("MyControll2", function (myProvider) {console.log ("MyControll2 - myProvider:" + myProvider.getValue ());});

Mở trong Fiddle JS

Bây giờ vì toàn bộ nhà máy của chúng tôi được tạo thành từ một đối tượng duy nhất, sẽ không hay nếu chúng tôi có thể cung cấp cho Angular chức năng xây dựng đối tượng thay vì phải viết nhà máy trông thú vị đó. Vâng, bạn là người may mắn, đây chính xác là dịch vụ.

Dịch vụ của bạn

Đây là cùng một mã ngoại trừ sử dụng một dịch vụ thay vì một nhà máy.

mod.service ("myProvider", function () {// THAY ĐỔI "nhà máy" thành "dịch vụ" // LƯU Ý rằng hàm duy nhất được truyền là hàm tạo đối tượng từ trước this.getValue = function () {return "Giá trị của tôi" ;};}); mod.contler ("MyContoder", function (myProvider) {console.log ("MyControll - myProvider:" + myProvider.getValue ());}); mod.contler ("MyControll2", function (myProvider) {console.log ("MyControll2 - myProvider:" + myProvider.getValue ());}); TIÊU THỤ ĐẦU RA MyContoder - myProvider: My Value MyControll2 - myProvider: My Value

Mở trong Fiddle JS

Nhà cung cấp vs Nhà máy vs Dịch vụ

Vì vậy, tóm lại, nhà cung cấp, nhà máy và dịch vụ đều là nhà cung cấp. Nhà máy là trường hợp đặc biệt của nhà cung cấp khi tất cả những gì bạn cần trong nhà cung cấp là hàm $ get (). Nó cho phép bạn viết nó với ít mã hơn. Dịch vụ là trường hợp đặc biệt của một nhà máy khi bạn muốn trả về một thể hiện của một đối tượng mới, với cùng lợi ích là viết ít mã hơn.

Khi nào nên sử dụng cái này so với cái kia?

Câu trả lời là bạn sử dụng phiên bản chuyên biệt nhất để hoàn thành mục tiêu của mình. Ví dụ, bạn đang trả về một đối tượng hiện có được xác định ở một nơi khác có tham số hàm tạo. Bạn không thể chuyển đối số cho dịch vụ, vì vậy bạn sẽ thực hiện cuộc gọi với nhà máy thay thế.

mod.factory ("myProvider", function () {console.log ("Hàm nhà máy được gọi."); trả về một số NewMessageBoxClass ("đối số tùy chỉnh");});

Một trong những yếu tố chính của việc quyết định giữa nhà cung cấp và nhà máy là liệu bạn có muốn định cấu hình đối tượng được tạo trước khi nó được tạo hay không. Bạn làm điều này bằng cách gọi module.config () và nhận một cá thể cho chính nhà cung cấp (thay vì đối tượng được nhà cung cấp trả về). Bạn làm điều này bằng cách nối thêm Nhà cung cấp dịch vụ trực tuyến vào cuối tên nhà cung cấp của bạn khi bạn tiêm nó.

Đây là một ví dụ về cách bạn sẽ làm điều đó:

mod.provider ("myProvider", function () {this.value = "My Value"; this.setValue = function (newValue) {this.value = newValue;}; this. $ get = function () {return this. giá trị; }; }); mod.contler ("MyContoder", function (myProvider) {console.log ("MyControll - myProvider:" + myProvider);}); mod.config (function (myProviderProvider) {// Phần cấu hình ADDED // Lưu ý thêm hậu tố "Nhà cung cấp" myProviderProvider.setValue ("Giá trị mới");});

Điều đó bao gồm khi nào nên sử dụng ba nhà cung cấp: nhà cung cấp, nhà máy và dịch vụ. Có một nhà cung cấp bổ sung không được đề cập ở đây, đó là một trường hợp đặc biệt khác và đó là nhà cung cấp giá trị.

Nếu bạn nhớ lần đầu tiên chúng tôi giới thiệu nhà cung cấp nhà máy ở trên, chúng tôi đã đưa ra ví dụ đơn giản về việc trả về giá trị chuỗi. Trông như thế này:

mod.factory ("myProvider", function () {return "Giá trị của tôi";});

Vâng, chúng tôi thực sự có thể đã làm điều đó bằng cách sử dụng nhà cung cấp giá trị thay vào đó, một lần nữa lợi ích là bạn có thể làm điều đó với ít mã hơn. Mã dưới đây thực hiện tương tự như mã ở trên:

mod.value ("myProvider", "Giá trị của tôi");

Vậy khi nào bạn sẽ sử dụng cái này so với cái kia? Có lẽ bạn sẽ sử dụng nhà máy sản xuất khi bạn muốn tính giá trị dựa trên một số dữ liệu khác, ví dụ dữ liệu từ nhà cung cấp giá trị khác hoặc nguồn bên ngoài. Và / hoặc khi bạn muốn tính giá trị khi và chỉ khi nó được yêu cầu lần đầu tiên. Dưới đây là một số ví dụ:

// Ví dụ trong đó nhà máy phụ thuộc vào nhà cung cấp "giá trị" mod.value ("bội", 3); mod.factory ("value", function (bội) {return 10 * bội;}); // Ví dụ trong đó nhà máy phụ thuộc vào dữ liệu ngoài mod.factory ("value", function (bội) {var many = getDateFromExternalPage (); return 10 * bội;});

Tôi đã ngụ ý rằng giá trị là nhà cung cấp duy nhất khác? Vâng, tôi đã nói dối, có một cái khác rất giống với giá trị với hai sự khác biệt nhỏ. Nhà cung cấp đó được gọi là hằng số.

Sự khác biệt giữa giá trị và hằng là giá trị được chỉ định sử dụng hằng có sẵn trong giai đoạn cấu hình. Bạn có thể nhớ từ trước rằng tôi đã đề cập rằng nhà cung cấp có thể truy cập được từ giai đoạn cấu hình, nhưng dịch vụ và nhà máy thì không.

Vâng, nó giống nhau về giá trị và hằng số. hằng có sẵn từ pha cấu hình và giá trị thì không. Sự khác biệt khác là như tên ngụ ý bạn không thể thay đổi giá trị của hằng số. Giá trị đầu tiên bạn gán cho nó là giá trị mà nó giữ, nếu bạn cố gán cho nó một giá trị khác thì nó sẽ bị bỏ qua.

Đây là một ví dụ:

mod.value ("myValue", "Bài tập đầu tiên"); mod.value ("myValue", "Nhiệm vụ thứ hai"); mod.constant ("myConstant", "Bài tập đầu tiên"); mod.constant ("myConstant", "Nhiệm vụ thứ hai"); mod.contler ("MyControll", function (myValue, myConstant) {console.log ("myValue:" + myValue); console.log ("myConstant:" + myConstant);}); TIÊU THỤ ĐẦU RA myValue: Nhiệm vụ thứ hai myConstant: Nhiệm vụ đầu tiên

Dưới đây là tóm tắt về thời điểm sử dụng từng:

giá trị

Bạn đang cung cấp một giá trị theo nghĩa đen đơn giản.

mod.value ("myValue", 10);
    

không thay đổi

Bạn cần có thể truy cập giá trị đó trong giai đoạn cấu hình. (sử dụng .config ())

mod.constant ("myValue", 10); mod.config (hàm (myValue) {console.log (myValue);});

nhà máy

Giá trị bạn đang cung cấp cần được tính toán dựa trên dữ liệu khác.

mod.factory ("myFactory", function () {return 10;});
        

dịch vụ

Bạn đang trả về một đối tượng với các phương thức.

mod.service ("myService", function () {var name = "Bob"; this.setName = function (newName) {this.name = newName;}; this.getName = function () {return this.name;} });
        

các nhà cung cấp

Bạn muốn có thể định cấu hình, trong giai đoạn cấu hình, đối tượng sẽ được tạo trước khi nó được tạo.

mod.provider ("helloer", function () {var name; this.setName = function (newName) {name = newName;}; this. $ get = function () {return new function () {this.sayHi = function () {console.log ("Hi" + name;};};};}); mod.config (function (helloerProvider) {helloerProvider.setName (siêu John ");});
        

Để lái xe về nhà lần cuối cùng ở đây là hình ảnh của một nhà cung cấp với các phần của nhà máy, giá trị và dịch vụ được tô sáng:


Câu trả lời 2:

Bên trong AngularJS đang sử dụng Factory để tạo Đối tượng dịch vụ và sử dụng Nhà cung cấp để tạo Đối tượng nhà máy.

Một nhà máy làm,

  1. Tạo một đối tượng / instanceConstruct / Khởi tạo đối tượng đã tạo / instancereturn đối tượng / thể hiện đã tạo

Để đặt bối cảnh, hãy xem Angular Factory là mẫu Thiết kế nhà máy trừu tượng. AngularJS cung cấp cho bạn tùy chọn để tạo đối tượng bạn chọn bằng phương thức xuất xưởng, bạn trả về đối tượng đã tạo cho ứng dụng của bạn để sử dụng làm dịch vụ.

Ví dụ bên dưới, bạn có lựa chọn giữa hai cổng thanh toán, ai đó sử dụng mã / thư viện của bạn, phương thức xuất xưởng của bạn có thể đưa ra lựa chọn nên tạo đối tượng Paypal hay Stripe. Điều này rất giống với Tóm tắt Factory, người dùng thanh toánService không biết dịch vụ nào được sử dụng cho cổng thanh toán.

var myModule = angular.module ('myModule', []); myModule.constant (Thanh toán thanh toánGatewayName, "Stripe"); // hoặc "Paypal" myModule.factory ('PaymentService', function (PaymentGatewayName) {var PaymentService; // bạn quyết định tạo đối tượng nào dựa trên nhu cầu kinh doanh // StripeGateway và PaypalGateway là các lớp JavaScript // chứa triển khai cụ thể của Gateway nếu ( PaymentGatewayName == "Stripe") {PaymentService = new StripeGateway (); // mã tùy chỉnh để khởi tạo cổng sọc}} (PaymentGatewayName == "Paypal") {PaymentService = new PaypalGateway (); // mã tùy chỉnh để khởi tạo paypal} / / mã tùy chỉnh để khởi tạo thanh toán Dịch vụ trả lại dịch vụ thanh toán;});

Mã dịch vụ trông như thế này, bạn chú ý từ khóa này, có nghĩa là, đối tượng đã được Angular Core tạo cho bạn, bạn không còn điều khiển việc tạo đối tượng nữa.

var myModule = angular.module ('myModule', []); myModule.service ('Cache', function () {var localVariable = ""; // không thể được truy cập bên ngoài this.cacheSize = 5; // 5 MB this.objectsSize = 1000; // max 1000 đối tượng this.put = function (khóa, giá trị) {...} this.get = function (get) {return ...}});

Câu trả lời 3:

Câu hỏi lớn trong AngularJS: Service vs Factory v / s Nhà cung cấp. Tôi nên dùng gì?

Có hàng tấn tài nguyên trên internet thảo luận về chủ đề này. Hóa ra câu hỏi này vẫn xuất hiện mỗi tuần hoặc lâu hơn trên các kênh khác nhau và ngay cả sau khi đọc mười câu trả lời hàng đầu trên StackOverflow, nó vẫn không rõ ràng lắm.

Nếu bạn nghĩ rằng chúng giống nhau - bạn đúng. Chúng rất giống nhau. Trong thực tế, tất cả họ đều giống nhau. Họ đều là nhà cung cấp.

Đọc toàn bộ bài viết -> AngularJS: Nhà cung cấp dịch vụ v / s Nhà máy v / s - Chuẩn bị phỏng vấn trong 15 phút