a

Câu hỏi AngularJS: Dịch vụ vs nhà cung cấp so với nhà máy


Sự khác biệt giữa một Service, Provider và Factory trong AngularJS?


3167
2018-03-27 17:59


gốc


Tôi thấy rằng tất cả các thuật ngữ Angular là đáng sợ cho người mới bắt đầu. Chúng tôi bắt đầu với bảng xếp hạng này dễ dàng hơn một chút để các lập trình viên của chúng tôi hiểu được khi học Angular demisx.github.io/angularjs/2014/09/14/…. Hy vọng điều này sẽ giúp đội của bạn quá. - demisx
Theo tôi, cách tốt nhất để hiểu sự khác biệt là sử dụng tài liệu của Angular: docs.angularjs.org/guide/providers nó được giải thích rất tốt và sử dụng một ví dụ đặc biệt để giúp bạn hiểu nó. - Rafael Merlin
@Blaise Cảm ơn bạn! Theo nhận xét của tôi trong bài đăng, tôi đã cố tình bỏ qua, vì 99% trường hợp sử dụng từ trải nghiệm của tôi có thể được xử lý thành công qua service.factory. Không muốn làm phức tạp thêm chủ đề này. - demisx
Tôi thấy cuộc thảo luận này cũng rất hữu ích stackoverflow.com/questions/18939709/… - Anand Gupta
Đây là một số câu trả lời hay khoảng cách services, factories và providers công trinh. - Mistalis


Các câu trả lời:


Từ danh sách gửi thư của AngularJS tôi nhận được một chủ đề tuyệt vời giải thích dịch vụ so với nhà cung cấp so với nhà cung cấp và việc sử dụng tiêm của họ. Biên dịch câu trả lời:

Dịch vụ

Cú pháp: module.service( 'serviceName', function ); 
Kết quả: Khi khai báo serviceName như một đối số có thể tiêm bạn sẽ được cung cấp một thể hiện của hàm. Nói cách khác  new FunctionYouPassedToService().

Nhà máy

Cú pháp: module.factory( 'factoryName', function ); 
Kết quả: Khi khai báo factoryName như một đối số được tiêm, bạn sẽ được cung cấp giá trị được trả về bằng cách gọi tham chiếu hàm được truyền tới module.factory.

Nhà cung cấp

Cú pháp: module.provider( 'providerName', function ); 
Kết quả: Khi khai báo providerName như một đối số có thể tiêm bạn sẽ được cung cấp  (new ProviderFunction()).$get(). Hàm khởi tạo được khởi tạo trước khi phương thức $ get được gọi - ProviderFunction là tham chiếu hàm được truyền tới module.provider.

Nhà cung cấp có lợi thế là họ có thể được cấu hình trong giai đoạn cấu hình mô-đun.

Xem đây cho mã được cung cấp.

Đây là lời giải thích tuyệt vời hơn của Misko:

provide.value('a', 123);

function Controller(a) {
  expect(a).toEqual(123);
}

Trong trường hợp này, kim phun đơn giản trả về giá trị. Nhưng nếu bạn muốn tính toán giá trị thì sao? Sau đó sử dụng một nhà máy

provide.factory('b', function(a) {
  return a*2;
});

function Controller(b) {
  expect(b).toEqual(246);
}

Vì thế factory là một hàm chịu trách nhiệm tạo ra giá trị. Lưu ý rằng chức năng của nhà máy có thể yêu cầu các phụ thuộc khác.

Nhưng nếu bạn muốn trở thành OO nhiều hơn và có một lớp được gọi là Greeter?

function Greeter(a) {
  this.greet = function() {
    return 'Hello ' + a;
  }
}

Sau đó, để nhanh chóng bạn sẽ phải viết

provide.factory('greeter', function(a) {
  return new Greeter(a);
});

Sau đó, chúng tôi có thể yêu cầu 'greeter' trong bộ điều khiển như thế này

function Controller(greeter) {
  expect(greeter instanceof Greeter).toBe(true);
  expect(greeter.greet()).toEqual('Hello 123');
}

Nhưng đó là cách quá dài dòng. Một cách ngắn hơn để viết điều này sẽ là provider.service('greeter', Greeter);

Nhưng nếu chúng ta muốn cấu hình Greeter lớp trước khi tiêm? Sau đó chúng ta có thể viết

provide.provider('greeter2', function() {
  var salutation = 'Hello';
  this.setSalutation = function(s) {
    salutation = s;
  }

  function Greeter(a) {
    this.greet = function() {
      return salutation + ' ' + a;
    }
  }

  this.$get = function(a) {
    return new Greeter(a);
  };
});

Sau đó, chúng ta có thể làm điều này:

angular.module('abc', []).config(function(greeter2Provider) {
  greeter2Provider.setSalutation('Halo');
});

function Controller(greeter2) {
  expect(greeter2.greet()).toEqual('Halo 123');
}

Như một lưu ý phụ, service, factoryvalue tất cả đều bắt nguồn từ nhà cung cấp.

provider.service = function(name, Class) {
  provider.provide(name, function() {
    this.$get = function($injector) {
      return $injector.instantiate(Class);
    };
  });
}

provider.factory = function(name, factory) {
  provider.provide(name, function() {
    this.$get = function($injector) {
      return $injector.invoke(factory);
    };
  });
}

provider.value = function(name, value) {
  provider.factory(name, function() {
    return value;
  });
};

2803
2017-07-30 10:20



Xem thêm stackoverflow.com/a/13763886/215945 thảo luận về sự khác biệt giữa dịch vụ và nhà máy. - Mark Rajcok
Trong chỉnh sửa 611 tôi đã thêm vào sử dụng các hằng số và giá trị góc. Để chứng minh sự khác biệt của người khác đã được hiển thị. jsbin.com/ohamub/611/edit - Nick
Mặc dù một dịch vụ được gọi bằng cách tạo một thể hiện của hàm. Nó thực sự được tạo ra chỉ một lần cho mỗi vòi phun mà làm cho nó giống như singleton.docs.angularjs.org/guide/dev_guide.services.creating_services - angelokh
Ví dụ này có thể không thể tin được nếu nó sử dụng một ví dụ thực tế rõ ràng. Tôi bị lạc cố gắng tìm ra điểm của những thứ như thế nào toEqual và greeter.Greet Là. Tại sao không sử dụng một cái gì đó hơi thực tế hơn và liên quan? - Kyle Pennell
Sử dụng hàm expect () là một sự lựa chọn nghèo nàn để giải thích một cái gì đó. Sử dụng mã thế giới thực trong lần tiếp theo. - Craig


Bản trình diễn JS Fiddle

Ví dụ "Hello world" với 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() {

    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 src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="MyCtrl">
    {{hellos}}
</div>
</body>


797
2018-05-15 15:53



Không this thay đổi ngữ cảnh trong $get chức năng? - bạn không còn tham chiếu đến nhà cung cấp đã được khởi tạo trong hàm đó nữa. - Nate-Wilkins
@Nate: this không thay đổi ngữ cảnh, thực ra, bởi vì những gì được gọi là new Provider(). $ get (), ở đâu Provider là hàm được chuyển đến app.provider. Đó là để nói rằng $get() đang được gọi là phương pháp xây dựng Provider, vì thế this sẽ đề cập đến Provider như ví dụ cho thấy. - Brandon
@ Brandon Ohh ok đó là kindof gọn gàng sau đó. Lúng túng ngay từ cái nhìn đầu tiên - cảm ơn vì đã làm rõ! - Nate-Wilkins
Tại sao tôi nhận được Unknown provider: helloWorldProvider <- helloWorld khi chạy nội bộ này? Nhận xét nó ra, cùng một lỗi cho 2 ví dụ khác. Có một số cấu hình nhà cung cấp ẩn không? (Góc 1.0.8) - Tìm thấy: stackoverflow.com/questions/12339272/… - Antoine
Có phải lý do tại sao @Antoine bị lỗi "Unknown provide: helloWorldProvider" vì trong mã .config của bạn, bạn sử dụng 'helloWorldProvider', nhưng khi bạn định nghĩa nhà cung cấp trong myApp.provider ('helloWorld', function ()), bạn sử dụng 'Chào thế giới'? Nói cách khác, trong mã cấu hình của bạn, góc nhìn biết bạn đang đề cập đến nhà cung cấp helloWorld như thế nào? Cảm ơn - jmtoung


TL; DR 

1) Khi bạn đang sử dụng Nhà máy bạn tạo một đối tượng, thêm các thuộc tính vào nó, sau đó trả về cùng một đối tượng đó. Khi bạn chuyển nhà máy này vào bộ điều khiển của bạn, các thuộc tính đó trên đối tượng sẽ có sẵn trong bộ điều khiển đó thông qua nhà máy của bạn.

app.controller(‘myFactoryCtrl’, function($scope, myFactory){
  $scope.artist = myFactory.getArtist();
});

app.factory(‘myFactory’, function(){
  var _artist = ‘Shakira’;
  var service = {};

  service.getArtist = function(){
    return _artist;
  }

  return service;
});


2) Khi bạn đang sử dụng Dịch vụ, AngularJS khởi tạo nó đằng sau hậu trường với từ khóa 'mới'. Do đó, bạn sẽ thêm thuộc tính vào ‘this’ và dịch vụ sẽ trả về ‘this’. Khi bạn chuyển dịch vụ vào bộ điều khiển của mình, các thuộc tính trên ‘this’ này sẽ có sẵn trên bộ điều khiển đó thông qua dịch vụ của bạn.

app.controller(‘myServiceCtrl’, function($scope, myService){
  $scope.artist = myService.getArtist();
});

app.service(‘myService’, function(){
  var _artist = ‘Nelly’;
  this.getArtist = function(){
    return _artist;
  }
});



3)  Nhà cung cấp là dịch vụ duy nhất bạn có thể chuyển vào hàm .config () của bạn. Sử dụng nhà cung cấp khi bạn muốn cung cấp cấu hình mô-đun cho đối tượng dịch vụ của mình trước khi cung cấp nó.

app.controller(‘myProvider’, function($scope, myProvider){
  $scope.artist = myProvider.getArtist();
  $scope.data.thingFromConfig = myProvider.thingOnConfig;
});

app.provider(‘myProvider’, function(){
 //Only the next two lines are available in the app.config()
 this._artist = ‘’;
 this.thingFromConfig = ‘’;
  this.$get = function(){
    var that = this;
    return {
      getArtist: function(){
        return that._artist;
      },
      thingOnConfig: that.thingFromConfig
    }
  }
});

app.config(function(myProviderProvider){
  myProviderProvider.thingFromConfig = ‘This was set in config’;
});



Không TL; DR

1) Nhà máy 
Nhà máy là cách phổ biến nhất để tạo và định cấu hình dịch vụ. Có thực sự không nhiều hơn những gì TL, DR nói. Bạn chỉ cần tạo một đối tượng, thêm các thuộc tính vào nó, sau đó trả về cùng một đối tượng đó. Sau đó, khi bạn chuyển nhà máy vào bộ điều khiển của bạn, các thuộc tính đó trên đối tượng sẽ có sẵn trong bộ điều khiển đó thông qua nhà máy của bạn. Một ví dụ rộng hơn là dưới đây.

app.factory(‘myFactory’, function(){
  var service = {};
  return service;
});

Bây giờ bất kỳ tài sản nào chúng tôi đính kèm vào ‘dịch vụ’ sẽ có sẵn cho chúng tôi khi chúng tôi chuyển ‘myFactory’ vào bộ điều khiển của chúng tôi.

Bây giờ, hãy thêm một số biến 'riêng tư' vào hàm gọi lại của chúng tôi. Những điều này sẽ không thể truy cập trực tiếp từ bộ điều khiển, nhưng cuối cùng chúng tôi sẽ thiết lập một số phương thức getter / setter trên ‘dịch vụ’ để có thể thay đổi các biến ‘riêng tư’ này khi cần.

app.factory(‘myFactory’, function($http, $q){
  var service = {};
  var baseUrl = ‘https://itunes.apple.com/search?term=’;
  var _artist = ‘’;
  var _finalUrl = ‘’;

  var makeUrl = function(){
   _artist = _artist.split(‘ ‘).join(‘+’);
    _finalUrl = baseUrl + _artist + ‘&callback=JSON_CALLBACK’;
    return _finalUrl
  }

  return service;
});

Ở đây bạn sẽ nhận thấy chúng tôi không đính kèm các biến / chức năng đó vào ‘dịch vụ’. Chúng tôi chỉ đơn giản là tạo chúng để sử dụng hoặc sửa đổi chúng sau này.

  • baseUrl là URL cơ sở mà API iTunes yêu cầu
  • _artist là nghệ sĩ chúng tôi muốn tra cứu
  • _finalUrl là URL cuối cùng và được xây dựng hoàn chỉnh mà chúng tôi sẽ thực hiện cuộc gọi tới iTunes
  • makeUrl là một hàm sẽ tạo và trả lại URL thân thiện với iTunes của chúng tôi.

Giờ đây, các biến số và biến số riêng tư / trợ giúp của chúng tôi đã sẵn sàng, hãy thêm một số thuộc tính vào đối tượng ‘dịch vụ’. Bất cứ điều gì chúng tôi đưa vào ‘dịch vụ’ có thể được sử dụng trực tiếp bên trong bất kỳ bộ điều khiển nào mà chúng tôi đưa vào ‘myFactory’.

Chúng ta sẽ tạo các phương thức setArtist và getArtist đơn giản là trả về hoặc thiết lập các nghệ sĩ. Chúng tôi cũng sẽ tạo một phương thức sẽ gọi API iTunes với URL được tạo của chúng tôi. Phương pháp này sẽ trả về một lời hứa sẽ hoàn thành sau khi dữ liệu đã trở lại từ iTunes API. Nếu bạn chưa có nhiều kinh nghiệm sử dụng các lời hứa trong AngularJS, tôi khuyên bạn nên thực hiện một bước nhảy sâu vào chúng.

Phía dưới setArtist chấp nhận một nghệ sĩ và cho phép bạn thiết lập các nghệ sĩ. getArtist trả về nghệ sĩ. callItunes đầu tiên gọi hàm makeUrl () để tạo URL chúng tôi sẽ sử dụng với yêu cầu $ http của chúng tôi. Sau đó, nó thiết lập một đối tượng lời hứa, thực hiện một yêu cầu $ http với url cuối cùng của chúng tôi, sau đó vì $ http trả về một lời hứa, chúng tôi có thể gọi .success hoặc .error sau khi yêu cầu của chúng tôi. Sau đó, chúng tôi sẽ giải quyết lời hứa của mình bằng dữ liệu iTunes hoặc chúng tôi từ chối lời nhắn với thông báo 'Đã xảy ra lỗi'.

app.factory('myFactory', function($http, $q){
  var service = {};
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }

  service.setArtist = function(artist){
    _artist = artist;
  }

  service.getArtist = function(){
    return _artist;
  }

  service.callItunes = function(){
    makeUrl();
    var deferred = $q.defer();
    $http({
      method: 'JSONP',
      url: _finalUrl
    }).success(function(data){
      deferred.resolve(data);
    }).error(function(){
      deferred.reject('There was an error')
    })
    return deferred.promise;
  }

  return service;
});

Bây giờ nhà máy của chúng tôi đã hoàn tất. Bây giờ chúng ta có thể tiêm ‘myFactory’ vào bất kỳ bộ điều khiển nào và sau đó chúng ta sẽ có thể gọi các phương thức mà chúng ta đã gắn với đối tượng dịch vụ của chúng ta (setArtist, getArtist và callItunes).

app.controller('myFactoryCtrl', function($scope, myFactory){
  $scope.data = {};
  $scope.updateArtist = function(){
    myFactory.setArtist($scope.data.artist);
  };

  $scope.submitArtist = function(){
    myFactory.callItunes()
      .then(function(data){
        $scope.data.artistData = data;
      }, function(data){
        alert(data);
      })
  }
});

Trong bộ điều khiển ở trên, chúng tôi đang tiêm dịch vụ ‘myFactory’. Sau đó, chúng tôi đặt thuộc tính trên đối tượng $ scope của chúng tôi với dữ liệu từ ‘myFactory’. Mã khó duy nhất ở trên là nếu bạn chưa từng xử lý lời hứa trước đây. Bởi vì callItunes đang trả về một lời hứa, chúng ta có thể sử dụng phương thức .then () và chỉ thiết lập $ scope.data.artistData khi lời hứa của chúng ta được đáp ứng với dữ liệu iTunes. Bạn sẽ nhận thấy bộ điều khiển của chúng tôi rất 'mỏng' (Đây là một thực hành mã hóa tốt). Tất cả các dữ liệu logic và liên tục của chúng tôi đều nằm trong dịch vụ của chúng tôi, không nằm trong bộ điều khiển của chúng tôi.

2) Dịch vụ 
Có lẽ điều quan trọng nhất cần biết khi giao dịch với việc tạo một Dịch vụ là nó được khởi tạo bằng từ khóa 'mới'. Đối với bạn rất kinh nghiệm JavaScript này sẽ cung cấp cho bạn một gợi ý lớn vào bản chất của mã. Đối với những người bạn có nền tảng hạn chế về JavaScript hoặc cho những người không quá quen thuộc với từ khóa 'mới' thực sự, hãy xem xét một số nguyên tắc cơ bản về JavaScript mà cuối cùng sẽ giúp chúng tôi hiểu bản chất của Dịch vụ.

Để thực sự thấy các thay đổi xảy ra khi bạn gọi hàm với từ khóa 'mới', hãy tạo hàm và gọi hàm đó bằng từ khóa 'mới', sau đó hãy hiển thị thông dịch viên sẽ làm gì khi thấy từ khóa 'mới'. Kết quả cuối cùng sẽ giống nhau.

Trước tiên hãy tạo Constructor của chúng tôi.

var Person = function(name, age){
  this.name = name;
  this.age = age;
}

Đây là một hàm tạo hàm JavaScript điển hình. Bây giờ bất cứ khi nào chúng ta gọi hàm Person bằng cách sử dụng từ khóa ‘mới’, ‘this’ sẽ bị ràng buộc với đối tượng mới được tạo ra.

Bây giờ, hãy thêm phương thức vào mẫu thử nghiệm của Nhân vật của chúng tôi để nó sẽ có sẵn trên mọi phiên bản của lớp ‘Người’ của chúng tôi.

Person.prototype.sayName = function(){
  alert(‘My name is ‘ + this.name);
}

Bây giờ, bởi vì chúng ta đặt hàm sayName trên nguyên mẫu, mọi cá thể của Person sẽ có thể gọi hàm sayName để cảnh báo tên của cá thể đó.

Bây giờ chúng ta đã có hàm dựng hàm Person của chúng ta và hàm sayName của chúng ta trên nguyên mẫu của nó, hãy tạo một cá thể Person, sau đó gọi hàm sayName.

var tyler = new Person(‘Tyler’, 23);
tyler.sayName(); //alerts ‘My name is Tyler’

Vì vậy, tất cả cùng nhau mã để tạo một hàm tạo Person, thêm một hàm vào nguyên mẫu của nó, tạo ra một cá thể Person, và sau đó gọi hàm trên nguyên mẫu của nó trông như thế này.

var Person = function(name, age){
  this.name = name;
  this.age = age;
}
Person.prototype.sayName = function(){
  alert(‘My name is ‘ + this.name);
}
var tyler = new Person(‘Tyler’, 23);
tyler.sayName(); //alerts ‘My name is Tyler’

Bây giờ, hãy xem những gì thực sự đang xảy ra khi bạn sử dụng từ khóa 'mới' trong JavaScript. Điều đầu tiên bạn nên lưu ý là sau khi sử dụng ‘mới’ trong ví dụ của chúng tôi, chúng tôi có thể gọi một phương thức (sayName) trên ‘tyler’ giống như nó là một đối tượng - đó là vì nó là. Đầu tiên, chúng ta biết rằng hàm tạo Person của chúng ta đang trả về một đối tượng, cho dù chúng ta có thể thấy rằng trong mã hay không. Thứ hai, chúng ta biết rằng bởi vì hàm sayName của chúng ta nằm trên nguyên mẫu và không trực tiếp trên cá thể Person, đối tượng mà hàm Person đang trả về phải được ủy quyền cho nguyên mẫu của nó trên các tra cứu không thành công. Nói một cách đơn giản hơn, khi chúng ta gọi tyler.sayName () thông dịch viên nói “OK, tôi sẽ xem xét đối tượng‘ tyler ’mà chúng ta vừa tạo, định vị hàm sayName, rồi gọi nó. Đợi đã, tôi không thấy nó ở đây - tất cả những gì tôi thấy là tên và tuổi, hãy để tôi kiểm tra nguyên mẫu. Yup, có vẻ như nó ở trên nguyên mẫu, hãy để tôi gọi nó. ”

Dưới đây là mã cho cách bạn có thể suy nghĩ về từ khóa 'mới' thực sự đang làm gì trong JavaScript. Về cơ bản, đây là một ví dụ về đoạn mã ở trên. Tôi đã đặt ‘chế độ xem thông dịch’ hoặc cách thông dịch viên nhìn thấy mã bên trong ghi chú.

var Person = function(name, age){
  //The below line creates an object(obj) that will delegate to the person’s prototype on failed lookups.
  //var obj = Object.create(Person.prototype);

  //The line directly below this sets ‘this’ to the newly created object
  //this = obj;

  this.name = name;
  this.age = age;

  //return this;
}

Bây giờ có kiến ​​thức về từ khóa 'mới' thực sự trong JavaScript, việc tạo Dịch vụ trong AngularJS sẽ dễ hiểu hơn.

Điều quan trọng nhất để hiểu khi tạo Dịch vụ là biết rằng Dịch vụ được khởi tạo bằng từ khóa 'mới'. Kết hợp kiến ​​thức đó với các ví dụ của chúng tôi ở trên, bây giờ bạn sẽ nhận ra rằng bạn sẽ đính kèm các thuộc tính và phương thức của mình trực tiếp vào ‘this’ mà sau đó sẽ được trả lại từ chính Dịch vụ. Chúng ta hãy nhìn vào điều này trong hành động.

Không giống như những gì chúng ta đã làm với ví dụ Factory, chúng ta không cần phải tạo một đối tượng, sau đó trả về đối tượng đó bởi vì, như đã đề cập nhiều lần trước, chúng ta sử dụng từ khóa 'new' để trình thông dịch sẽ tạo đối tượng đó, đó là nguyên mẫu, sau đó trả lại cho chúng tôi mà không cần phải thực hiện công việc.

Trước tiên, hãy tạo chức năng "riêng tư" và trợ giúp của chúng tôi. Điều này sẽ rất quen thuộc vì chúng tôi đã làm điều tương tự với nhà máy của chúng tôi. Tôi sẽ không giải thích những gì từng dòng ở đây vì tôi đã làm điều đó trong ví dụ của nhà máy, nếu bạn nhầm lẫn, hãy đọc lại ví dụ về nhà máy.

app.service('myService', function($http, $q){
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }
});

Bây giờ, chúng tôi sẽ đính kèm tất cả các phương pháp của chúng tôi sẽ có sẵn trong bộ điều khiển của chúng tôi để ‘this’.

app.service('myService', function($http, $q){
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }

  this.setArtist = function(artist){
    _artist = artist;
  }

  this.getArtist = function(){
    return _artist;
  }

  this.callItunes = function(){
    makeUrl();
    var deferred = $q.defer();
    $http({
      method: 'JSONP',
      url: _finalUrl
    }).success(function(data){
      deferred.resolve(data);
    }).error(function(){
      deferred.reject('There was an error')
    })
    return deferred.promise;
  }

});

Bây giờ giống như trong nhà máy của chúng tôi, setArtist, getArtist và callItunes sẽ có sẵn trong bất kỳ bộ điều khiển nào chúng tôi chuyển myService vào. Đây là bộ điều khiển myService (gần như chính xác giống như bộ điều khiển nhà máy của chúng tôi).

app.controller('myServiceCtrl', function($scope, myService){
  $scope.data = {};
  $scope.updateArtist = function(){
    myService.setArtist($scope.data.artist);
  };

  $scope.submitArtist = function(){
    myService.callItunes()
      .then(function(data){
        $scope.data.artistData = data;
      }, function(data){
        alert(data);
      })
  }
});

Như tôi đã đề cập trước đây, một khi bạn thực sự hiểu những gì ‘mới’, Dịch vụ gần như giống hệt với các nhà máy ở AngularJS.

3) Nhà cung cấp

Điều quan trọng nhất cần nhớ về Nhà cung cấp là họ là dịch vụ duy nhất mà bạn có thể chuyển vào phần app.config của ứng dụng của bạn. Điều này rất quan trọng nếu bạn cần thay đổi một số phần của đối tượng dịch vụ của mình trước khi nó có sẵn ở mọi nơi khác trong ứng dụng của bạn. Mặc dù rất giống với Dịch vụ / Nhà máy, có một vài khác biệt mà chúng tôi sẽ thảo luận.

Trước tiên, chúng tôi thiết lập Nhà cung cấp của mình theo cách tương tự như với Dịch vụ và Nhà máy của chúng tôi. Các biến bên dưới là hàm ‘riêng tư’ và trợ giúp của chúng tôi.

app.provider('myProvider', function(){
   var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  //Going to set this property on the config function below.
  this.thingFromConfig = ‘’;

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }
}

* Một lần nữa nếu bất kỳ phần nào của mã trên gây nhầm lẫn, hãy xem phần Nhà máy nơi tôi giải thích tất cả những gì nó làm chi tiết hơn.

Bạn có thể nghĩ về các nhà cung cấp khi có ba phần. Phần đầu tiên là các biến / hàm 'riêng tư' sẽ được sửa đổi / đặt sau (được hiển thị ở trên). Phần thứ hai là các biến / hàm sẽ có sẵn trong hàm app.config của bạn và do đó có sẵn để thay đổi trước khi chúng có sẵn ở bất kỳ nơi nào khác (cũng được hiển thị ở trên). Điều quan trọng cần lưu ý là các biến đó cần được đính kèm với từ khóa ‘này’. Trong ví dụ của chúng tôi, chỉ có ‘thingFromConfig’ sẽ có sẵn để thay đổi trong app.config. Phần thứ ba (được hiển thị bên dưới) là tất cả các biến / chức năng sẽ có sẵn trong bộ điều khiển của bạn khi bạn chuyển dịch vụ ‘myProvider’ vào bộ điều khiển cụ thể đó.

Khi tạo một dịch vụ với nhà cung cấp, các thuộc tính / phương thức duy nhất sẽ có sẵn trong bộ điều khiển của bạn là các thuộc tính / phương thức được trả về từ hàm $ get (). Mã dưới đây đặt $ get vào ‘this’ (mà chúng tôi biết cuối cùng sẽ được trả về từ chức năng đó). Bây giờ, hàm $ get trả về tất cả các phương thức / thuộc tính mà chúng ta muốn có sẵn trong bộ điều khiển. Dưới đây là ví dụ về mã.

this.$get = function($http, $q){
    return {
      callItunes: function(){
        makeUrl();
        var deferred = $q.defer();
        $http({
          method: 'JSONP',
          url: _finalUrl
        }).success(function(data){
          deferred.resolve(data);
        }).error(function(){
          deferred.reject('There was an error')
        })
        return deferred.promise;
      },
      setArtist: function(artist){
        _artist = artist;
      },
      getArtist: function(){
        return _artist;
      },
      thingOnConfig: this.thingFromConfig
    }
  }

Bây giờ mã nhà cung cấp đầy đủ trông như thế này

app.provider('myProvider', function(){
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  //Going to set this property on the config function below
  this.thingFromConfig = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }

  this.$get = function($http, $q){
    return {
      callItunes: function(){
        makeUrl();
        var deferred = $q.defer();
        $http({
          method: 'JSONP',
          url: _finalUrl
        }).success(function(data){
          deferred.resolve(data);
        }).error(function(){
          deferred.reject('There was an error')
        })
        return deferred.promise;
      },
      setArtist: function(artist){
        _artist = artist;
      },
      getArtist: function(){
        return _artist;
      },
      thingOnConfig: this.thingFromConfig
    }
  }
});

Bây giờ giống như trong nhà máy và Dịch vụ của chúng tôi, setArtist, getArtist và callItunes sẽ có sẵn trong bất kỳ bộ điều khiển nào chúng tôi chuyển myProvider vào. Đây là bộ điều khiển myProvider (gần như chính xác giống như bộ điều khiển dịch vụ / nhà máy của chúng tôi).

app.controller('myProviderCtrl', function($scope, myProvider){
  $scope.data = {};
  $scope.updateArtist = function(){
    myProvider.setArtist($scope.data.artist);
  };

  $scope.submitArtist = function(){
    myProvider.callItunes()
      .then(function(data){
        $scope.data.artistData = data;
      }, function(data){
        alert(data);
      })
  }

  $scope.data.thingFromConfig = myProvider.thingOnConfig;
});

Như đã đề cập trước đây, toàn bộ điểm tạo dịch vụ với Nhà cung cấp là có thể thay đổi một số biến thông qua hàm app.config trước khi đối tượng cuối cùng được chuyển đến phần còn lại của ứng dụng. Chúng ta hãy xem một ví dụ về điều đó.

app.config(function(myProviderProvider){
  //Providers are the only service you can pass into app.config
  myProviderProvider.thingFromConfig = 'This sentence was set in app.config. Providers are the only service that can be passed into config. Check out the code to see how it works';
});

Bây giờ bạn có thể thấy cách ‘thingFromConfig’ là chuỗi rỗng trong nhà cung cấp của chúng tôi, nhưng khi xuất hiện trong DOM, nó sẽ là ‘Câu này được đặt…’.


619
2017-12-24 13:15



Phần duy nhất bị thiếu trong phần ghi tuyệt vời này là lợi thế tương đối của việc sử dụng dịch vụ trên một nhà máy; được giải thích rõ ràng trong câu trả lời được chấp nhận bởi Lior - infinity
FWIW (có thể không nhiều), đây là một blogger có vấn đề với Angular, và không thích providerProvider codeofrob.com/entries/you-have-ruined-javascript.html - barlop
Cú đấm của 'Gurus JavaScript' rất tinh quái. : D Tôi nghĩ câu trả lời này rất rõ ràng. Tuyệt vời bằng văn bản. - amarmishra
TLDR của bạn cần TLDR. - JensB
@ JensB tl; dr - Tìm hiểu phản ứng. - Tyler McGinnis


Tất cả các dịch vụ đều là singletons; chúng được khởi tạo một lần cho mỗi ứng dụng. Chúng có thể là thuộc bất kỳ loại nào, cho dù đó là một nguyên thủy, đối tượng theo nghĩa đen, hàm, hay thậm chí là một thể hiện của một kiểu tùy chỉnh.

Các value, factory, service, constantprovider phương pháp là tất cả các nhà cung cấp. Họ dạy cho Injector cách khởi tạo Dịch vụ.

Các tiết nhất, nhưng cũng là một trong những toàn diện nhất là một nhà cung cấp   công thức. Các còn lại bốn các loại công thức - Giá trị, Nhà máy, Dịch vụ và   Không thay đổi - chỉ là cú pháp trên đầu công thức của nhà cung cấp.

  • Các Công thức giá trị là trường hợp đơn giản nhất, nơi bạn tự khởi tạo Dịch vụ và cung cấp giá trị khởi tạo để các vòi phun.
  • Các Công thức nhà máy cung cấp cho các Injector một chức năng nhà máy mà nó gọi khi nó cần để nhanh chóng dịch vụ. Khi được gọi, chức năng nhà máy tạo và trả về cá thể dịch vụ. Các phụ thuộc của Dịch vụ được tiêm như các đối số của hàm. Vì vậy, sử dụng công thức này sẽ bổ sung thêm các khả năng sau:
    • Khả năng sử dụng các dịch vụ khác (có phụ thuộc)
    • Khởi tạo dịch vụ
    • Trì hoãn / khởi tạo lười biếng
  • Các Công thức dịch vụ gần giống như công thức Factory, nhưng ở đây Injector gọi constructor với toán tử mới thay vì chức năng của nhà máy.
  • Các Công thức nhà cung cấp thường là quá mức. Nó cho biết thêm một lớp của indirection bằng cách cho phép bạn cấu hình việc tạo ra các nhà máy.

Bạn chỉ nên sử dụng công thức Nhà cung cấp khi bạn muốn hiển thị API   cho cấu hình ứng dụng phải được thực hiện trước   ứng dụng bắt đầu. Điều này thường chỉ thú vị để tái sử dụng   các dịch vụ có hành vi có thể cần thay đổi đôi chút giữa   các ứng dụng.


506
2018-02-01 12:58



Vì vậy, dịch vụ và nhà máy về cơ bản giống nhau? Sử dụng một trong những khác cung cấp không có gì khác hơn là cú pháp thay thế? - Matt
@ Mc, vâng, dịch vụ là một cách ngắn gọn khi bạn đã có chức năng của riêng bạn mà bạn muốn để lộ như một dịch vụ. Từ tài liệu: myApp.factory ('unicornLauncher', ["apiToken", hàm (apiToken) {return new UnicornLauncher (apiToken);}]); vs: myApp.service ('unicornLauncher', ["apiToken", UnicornLauncher]); - janek
@joshperry Là một newbie, tôi đã googled sự khác biệt giữa dịch vụ và nhà máy trong một thời gian. Tôi đồng ý đây là câu trả lời hay nhất từ ​​trước tới nay! Tôi muốn hiểu dịch vụ dưới dạng lớp dịch vụ (ví dụ: bộ mã hóa / bộ giải mã), có thể có một số thuộc tính riêng tư. Và nhà máy cung cấp một tập hợp các phương thức trợ giúp không trạng thái. - stanleyxu2005
Ví dụ Yaa trong các câu trả lời khác ở trên không giải thích rõ ràng về các dịch vụ và nhà cung cấp b / w khác biệt cốt lõi là những gì được tiêm vào thời điểm các công thức này được khởi tạo. - Ashish Singh


Tìm hiểu Nhà máy, Dịch vụ và Nhà cung cấp AngularJS

Tất cả chúng được sử dụng để chia sẻ các đối tượng singleton tái sử dụng. Nó giúp chia sẻ mã tái sử dụng trên ứng dụng của bạn / các thành phần / mô-đun khác nhau.

Từ Tài liệu Dịch vụ / Nhà máy:

  • Lazely instantiated - Góc chỉ instantiates một dịch vụ / nhà máy khi một thành phần ứng dụng phụ thuộc vào nó.
  • Singletons - Mỗi thành phần   phụ thuộc vào một dịch vụ được tham chiếu đến một cá thể   được tạo bởi nhà máy dịch vụ.

Nhà máy

Một nhà máy là chức năng mà bạn có thể thao tác / thêm logic trước khi tạo một đối tượng, sau đó đối tượng mới được tạo sẽ được trả về.

app.factory('MyFactory', function() {
    var serviceObj = {};
    //creating an object with methods/functions or variables
    serviceObj.myFunction = function() {
        //TO DO:
    };
    //return that object
    return serviceObj;
});

Sử dụng

Nó có thể chỉ là một tập hợp các hàm giống như một lớp. Do đó, nó có thể được instantiated trong bộ điều khiển khác nhau khi bạn đang tiêm nó bên trong của bạn điều khiển / nhà máy / chức năng chỉ thị. Nó được khởi tạo chỉ một lần cho mỗi ứng dụng.

Dịch vụ

Đơn giản chỉ cần nhìn vào các dịch vụ suy nghĩ về nguyên mẫu mảng. Một dịch vụ là một hàm khởi tạo một đối tượng mới bằng cách sử dụng từ khóa 'mới'. Bạn có thể thêm các thuộc tính và hàm vào một đối tượng dịch vụ bằng cách sử dụng thistừ khóa. Không giống như một nhà máy, nó không trả về bất cứ thứ gì (nó trả về một đối tượng chứa các phương thức / thuộc tính).

app.service('MyService', function() {
    //directly binding events to this context
    this.myServiceFunction = function() {
        //TO DO:
    };
});

Sử dụng

Sử dụng nó khi bạn cần chia sẻ một đối tượng duy nhất trong suốt ứng dụng. Ví dụ: chi tiết người dùng được xác thực, phương pháp / dữ liệu có thể chia sẻ, chức năng Tiện ích, v.v.

Các nhà cung cấp

Một nhà cung cấp được sử dụng để tạo ra một đối tượng dịch vụ có thể cấu hình. Bạn có thể cấu hình cài đặt dịch vụ từ chức năng cấu hình. Nó trả về một giá trị bằng cách sử dụng $get() chức năng. Các $get chức năng được thực hiện trên pha chạy trong góc.

app.provider('configurableService', function() {
    var name = '';
    //this method can be be available at configuration time inside app.config.
    this.setName = function(newName) {
        name = newName;
    };
    this.$get = function() {
        var getName = function() {
             return name;
        };
        return {
            getName: getName //exposed object to where it gets injected.
        };
    };
});

Sử dụng

Khi bạn cần phải cung cấp cấu hình mô-đun khôn ngoan cho đối tượng dịch vụ của bạn trước khi làm cho nó có sẵn, ví dụ như. giả sử bạn muốn đặt URL API của mình trên cơ sở Môi trường như dev, stage hoặc là prod

CHÚ THÍCH 

Chỉ có nhà cung cấp sẽ có sẵn trong giai đoạn cấu hình của góc, trong khi   dịch vụ & nhà máy là không.

Hy vọng điều này đã làm sáng tỏ sự hiểu biết của bạn về Nhà máy, Dịch vụ và Nhà cung cấp.


221
2017-11-14 06:25



Tôi sẽ làm gì nếu tôi muốn có một dịch vụ với một giao diện cụ thể, nhưng có hai triển khai khác nhau, và tiêm từng bộ điều khiển nhưng gắn với các trạng thái khác nhau bằng cách sử dụng ui-router? ví dụ. thực hiện cuộc gọi từ xa ở một trạng thái, nhưng ghi vào bộ nhớ cục bộ thay cho một bộ nhớ khác. Các tài liệu của nhà cung cấp nói để sử dụng only when you want to expose an API for application-wide configuration that must be made before the application starts. This is usually interesting only for reusable services whose behavior might need to vary slightly between applications, do đó, không âm thanh có thể, phải không? - qix


Đối với tôi, sự mặc khải đến khi tôi nhận ra rằng họ đều làm việc theo cùng một cách: bằng cách chạy một cái gì đó Một lần, lưu trữ giá trị mà chúng nhận được và sau đó ho cùng một giá trị được lưu trữ khi được tham chiếu qua tiêm phụ thuộc.

Giả sử chúng ta có:

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

Sự khác biệt giữa ba là:

  1. aGiá trị được lưu trữ đến từ chạy fn.
  2. bGiá trị được lưu trữ đến từ newing fn.
  3. cGiá trị được lưu trữ đến từ lần đầu tiên nhận được một thể hiện bằng newing fnvà sau đó chạy $get phương pháp của cá thể.

Điều đó có nghĩa là có thứ gì đó giống như đối tượng bộ nhớ cache bên trong AngularJS, giá trị của mỗi lần tiêm chỉ được gán một lần, khi chúng được tiêm lần đầu tiên và ở đâu:

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

Đây là lý do chúng tôi sử dụng this trong các dịch vụ và xác định this.$get trong các nhà cung cấp.


190
2017-07-22 11:39



Tôi cũng thích câu trả lời này nhất. Điểm của tất cả chúng là cung cấp quyền truy cập vào một đối tượng bất cứ khi nào cần thông qua DI. Thông thường bạn đang làm tốt với factoryS. Lý do duy nhất services tồn tại là các ngôn ngữ như CoffeeScript, TypeScript, ES6 vv để bạn có thể sử dụng cú pháp lớp của chúng. Bạn cần providers chỉ khi mô-đun của bạn được sử dụng trong một số ứng dụng với các cài đặt khác nhau bằng cách sử dụng app.config(). Nếu dịch vụ của bạn là một singleton thuần túy hoặc có thể tạo ra các cá thể của một cái gì đó chỉ phụ thuộc vào việc thực hiện của bạn. - Andreas Linnert


Dịch vụ so với nhà cung cấp so với nhà máy:

Tôi đang cố giữ nó đơn giản. Đó là tất cả về khái niệm JavaScript cơ bản.

Trước hết, hãy nói về dịch vụ trong AngularJS!

Dịch vụ là gì: Trong AngularJS, Dịch vụ không là gì ngoài một đối tượng JavaScript đơn lẻ có thể lưu trữ một số phương thức hoặc thuộc tính hữu ích. Đối tượng singleton này được tạo cho mỗi ứng dụng ngApp (Angular app) và được chia sẻ giữa tất cả các bộ điều khiển trong ứng dụng hiện tại. Khi Angularjs khởi tạo một đối tượng dịch vụ, nó sẽ đăng ký đối tượng dịch vụ này với một tên dịch vụ duy nhất. Vì vậy, mỗi khi chúng ta cần bản ghi dịch vụ, Angular tìm kiếm sổ đăng ký cho tên dịch vụ này và nó trả về tham chiếu đến đối tượng dịch vụ. Như vậy chúng ta có thể gọi phương thức, truy cập các thuộc tính vv trên đối tượng dịch vụ. Bạn có thể đặt câu hỏi liệu bạn có thể đặt thuộc tính, phương thức trên đối tượng phạm vi của bộ điều khiển không! Vậy tại sao bạn cần đối tượng dịch vụ? Câu trả lời là: các dịch vụ được chia sẻ giữa nhiều phạm vi điều khiển. Nếu bạn đặt một số thuộc tính / phương thức trong đối tượng phạm vi của bộ điều khiển, nó sẽ chỉ có sẵn cho phạm vi hiện tại. Nhưng khi bạn định nghĩa các phương thức, các thuộc tính trên đối tượng dịch vụ, nó sẽ có sẵn trên toàn cầu và có thể được truy cập trong phạm vi bất kỳ bộ điều khiển nào bằng cách tiêm dịch vụ đó.

Vì vậy, nếu có ba phạm vi điều khiển, hãy để nó được controllerA, controllerB và controllerC, tất cả sẽ chia sẻ cùng một trường hợp dịch vụ.

<div ng-controller='controllerA'>
    <!-- controllerA scope -->
</div>
<div ng-controller='controllerB'>
    <!-- controllerB scope -->
</div>
<div ng-controller='controllerC'>
    <!-- controllerC scope -->
</div>

Cách tạo dịch vụ?

AngularJS cung cấp các phương thức khác nhau để đăng ký một dịch vụ. Ở đây chúng ta sẽ tập trung vào ba phương thức nhà máy (..), dịch vụ (..), nhà cung cấp (..);

Sử dụng liên kết này để tham chiếu mã

Chức năng nhà máy:

Chúng ta có thể định nghĩa một chức năng của nhà máy như dưới đây.

factory('serviceName',function fnFactory(){ return serviceInstance;})

AngularJS cung cấp 'factory (' serviceName ', fnFactory)' phương thức nhận hai tham số, tên dịch vụ và hàm JavaScript. Angular tạo cá thể dịch vụ bằng cách gọi hàm fnFactory () chẳng hạn như dưới đây.

var serviceInstace = fnFactory();

Hàm được truyền có thể định nghĩa một đối tượng và trả về đối tượng đó. AngularJS đơn giản lưu trữ tham chiếu đối tượng này vào một biến được chuyển làm đối số đầu tiên. Bất kỳ thứ gì được trả về từ fnFactory sẽ bị ràng buộc với serviceInstance. Thay vì trả về đối tượng, chúng ta cũng có thể trả về hàm, giá trị, v.v. Dù chúng ta sẽ trả về, sẽ có sẵn cho cá thể dịch vụ.

Thí dụ:

var app= angular.module('myApp', []);
//creating service using factory method
app.factory('factoryPattern',function(){
  var data={
    'firstName':'Tom',
    'lastName':' Cruise',
    greet: function(){
      console.log('hello!' + this.firstName + this.lastName);
    }
  };

  //Now all the properties and methods of data object will be available in our service object
  return data;
});

Chức năng dịch vụ:

service('serviceName',function fnServiceConstructor(){})

Đó là một cách khác, chúng ta có thể đăng ký một dịch vụ. Sự khác biệt duy nhất là cách AngularJS cố gắng khởi tạo đối tượng dịch vụ. Góc thời gian này sử dụng từ khóa 'mới' và gọi hàm khởi tạo giống như dưới đây.

var serviceInstance = new fnServiceConstructor();

Trong hàm hàm tạo, chúng ta có thể sử dụng từ khóa 'this' để thêm các thuộc tính / phương thức vào đối tượng dịch vụ. thí dụ:

//Creating a service using the service method
var app= angular.module('myApp', []);
app.service('servicePattern',function(){
  this.firstName ='James';
  this.lastName =' Bond';
  this.greet = function(){
    console.log('My Name is '+ this.firstName + this.lastName);
  };
});

Chức năng của nhà cung cấp:

Hàm Provider () là một cách khác để tạo các dịch vụ. Hãy để chúng tôi quan tâm để tạo ra một dịch vụ mà chỉ hiển thị một số tin nhắn chúc mừng cho người dùng. Nhưng chúng tôi cũng muốn cung cấp một chức năng như vậy mà người dùng có thể thiết lập thông điệp chào mừng của riêng họ. Về mặt kỹ thuật, chúng tôi muốn tạo các dịch vụ có thể cấu hình. Làm thế nào chúng ta có thể làm điều này ? Phải có một cách, để ứng dụng có thể truyền thông điệp chào mừng tùy chỉnh của họ và Angularjs sẽ làm cho nó có sẵn cho chức năng nhà máy / constructor tạo ra thể hiện dịch vụ của chúng ta. Trong trường hợp như vậy provider () chức năng làm công việc. sử dụng hàm provider (), chúng ta có thể tạo các dịch vụ có thể cấu hình.

Chúng ta có thể tạo các dịch vụ cấu hình bằng cách sử dụng cú pháp của nhà cung cấp như được đưa ra dưới đây.

/*step1:define a service */
app.provider('service',function serviceProviderConstructor(){});

/*step2:configure the service */
app.config(function configureService(serviceProvider){});

Cú pháp của nhà cung cấp nội bộ hoạt động như thế nào?

1.Provider đối tượng được tạo ra bằng cách sử dụng hàm xây dựng, chúng tôi được định nghĩa trong chức năng nhà cung cấp của chúng tôi.

var serviceProvider = new serviceProviderConstructor();

2.Các chức năng chúng tôi đã thông qua trong app.config (), được thực hiện. Điều này được gọi là giai đoạn cấu hình, và ở đây chúng tôi có cơ hội để tùy chỉnh dịch vụ của chúng tôi.

configureService(serviceProvider);

3.Finally dịch vụ dụ được tạo ra bằng cách gọi $ get phương pháp của serviceProvider.

serviceInstance = serviceProvider.$get()

Mã mẫu để tạo dịch vụ bằng cách sử dụng cú pháp cung cấp:

var app= angular.module('myApp', []);
app.provider('providerPattern',function providerConstructor(){
  //this function works as constructor function for provider
  this.firstName = 'Arnold ';
  this.lastName = ' Schwarzenegger' ;
  this.greetMessage = ' Welcome, This is default Greeting Message' ;
  //adding some method which we can call in app.config() function
  this.setGreetMsg = function(msg){
    if(msg){
      this.greetMessage =  msg ;
    }
  };

  //We can also add a method which can change firstName and lastName
  this.$get = function(){
    var firstName = this.firstName;
    var lastName = this.lastName ;
    var greetMessage = this.greetMessage;
    var data={
       greet: function(){
         console.log('hello, ' + firstName + lastName+'! '+ greetMessage);
       }
    };
    return data ;
  };
});

app.config(
  function(providerPatternProvider){
    providerPatternProvider.setGreetMsg(' How do you do ?');
  }
);

Demo làm việc

Tóm lược:


Nhà máy sử dụng hàm factory trả về một thể hiện dịch vụ. serviceInstance = fnFactory ();

Dịch vụ sử dụng hàm xây dựng và Angular gọi hàm khởi tạo này bằng cách sử dụng từ khóa 'mới' để tạo cá thể dịch vụ. serviceInstance = new fnServiceConstructor ();

Các nhà cung cấp định nghĩa một hàm providerConstructor, hàm providerConstructor này định nghĩa một hàm nhà máy $ get . Angular gọi $ get () để tạo đối tượng dịch vụ. Cú pháp của nhà cung cấp có thêm lợi thế về việc cấu hình đối tượng dịch vụ trước khi nó được khởi tạo. serviceInstance = $ get ();


133
2017-11-19 13:36