Pertanyaan AngularJS: Layanan vs penyedia vs pabrik


Apa perbedaan antara a Service, Provider dan Factory di AngularJS?


3163
2018-03-27 17:59


asal


Jawaban:


Dari milis AngularJS yang saya dapatkan sebuah thread yang luar biasa yang menjelaskan layanan vs pabrik vs penyedia dan penggunaan injeksi mereka. Menyusun jawaban:

Jasa

Sintaksis: module.service( 'serviceName', function ); 
Hasil: Saat mendeklarasikan serviceName sebagai argumen yang dapat disuntikkan Anda akan diberikan contoh fungsi. Dengan kata lain  new FunctionYouPassedToService().

Pabrik

Sintaksis: module.factory( 'factoryName', function ); 
Hasil: Saat mendeklarasikan factoryName sebagai argumen yang dapat disuntikkan, Anda akan diberikan nilai yang dikembalikan dengan menjalankan referensi fungsi yang diteruskan ke module.factory.

Penyedia

Sintaksis: module.provider( 'providerName', function ); 
Hasil: Saat mendeklarasikan providerName sebagai argumen yang dapat disuntikkan Anda akan diberikan  (new ProviderFunction()).$get(). Fungsi konstruktor dibuat sebelum metode $ get dipanggil - ProviderFunction adalah referensi fungsi yang diteruskan ke module.provider.

Penyedia memiliki keuntungan bahwa mereka dapat dikonfigurasi selama fase konfigurasi modul.

Lihat sini untuk kode yang disediakan.

Berikut penjelasan lebih lanjut dari Misko:

provide.value('a', 123);

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

Dalam hal ini injektor hanya mengembalikan nilai sebagaimana adanya. Tetapi bagaimana jika Anda ingin menghitung nilainya? Kemudian gunakan pabrik

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

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

Begitu factory adalah fungsi yang bertanggung jawab untuk menciptakan nilai. Perhatikan bahwa fungsi pabrik dapat meminta dependensi lainnya.

Tetapi bagaimana jika Anda ingin menjadi lebih OO dan memiliki kelas yang disebut Greeter?

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

Kemudian untuk instantiate Anda harus menulis

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

Lalu kita bisa meminta 'penyambut' di controller seperti ini

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

Tapi itu terlalu bertele-tele. Cara yang lebih pendek untuk menulis ini adalah provider.service('greeter', Greeter);

Tetapi bagaimana jika kita ingin mengkonfigurasi Greeter kelas sebelum injeksi? Lalu kita bisa menulis

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);
  };
});

Maka kita bisa melakukan ini:

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

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

Sebagai catatan tambahan, service, factory, dan value semuanya berasal dari provider.

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;
  });
};

2800
2017-07-30 10:20



Demo JS Fiddle

Contoh "Hello world" dengan 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>


796
2018-05-15 15:53



TL; DR 

1) Saat Anda menggunakan Pabrik Anda membuat objek, menambahkan properti ke dalamnya, lalu mengembalikan objek yang sama. Ketika Anda mengirimkan pabrik ini ke pengontrol Anda, properti-properti tersebut pada objek sekarang akan tersedia di pengontrol itu melalui pabrik Anda.

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) Saat Anda menggunakan Layanan, AngularJS memberi contoh di balik layar dengan kata kunci 'baru'. Karena itu, Anda akan menambahkan properti ke ‘ini’ dan layanan akan mengembalikan ‘ini’. Saat Anda meneruskan layanan ke pengontrol Anda, properti tersebut pada 'ini' sekarang akan tersedia di pengontrol tersebut melalui layanan Anda.

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

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



3)  Penyedia adalah satu-satunya layanan yang dapat Anda berikan ke fungsi .config () Anda. Gunakan penyedia ketika Anda ingin memberikan konfigurasi modul-lebar untuk objek layanan Anda sebelum membuatnya tersedia.

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’;
});



Non TL; DR

1) Pabrik 
Pabrik adalah cara paling populer untuk membuat dan mengonfigurasi layanan. Ada benar-benar tidak lebih dari apa yang TL; DR kata. Anda cukup membuat objek, tambahkan properti ke dalamnya, lalu kembalikan objek yang sama. Kemudian ketika Anda memasukkan pabrik ke pengontrol Anda, properti tersebut pada objek sekarang akan tersedia di pengontrol itu melalui pabrik Anda. Contoh yang lebih luas ada di bawah.

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

Sekarang, properti apa pun yang kami lampirkan ke 'layanan' akan tersedia bagi kami ketika kami meneruskan 'myFactory' ke pengontrol kami.

Sekarang mari tambahkan beberapa variabel 'pribadi' ke fungsi panggil balik kami. Ini tidak akan dapat diakses langsung dari pengontrol, tetapi pada akhirnya kami akan menyiapkan beberapa metode pengambil / penyetel pada 'layanan' untuk dapat mengubah variabel 'pribadi' ini saat diperlukan.

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;
});

Di sini Anda akan melihat bahwa kami tidak melampirkan variabel / fungsi tersebut ke ‘layanan’. Kami hanya membuat mereka untuk menggunakan atau memodifikasinya nanti.

  • baseUrl adalah URL dasar yang diperlukan oleh API iTunes
  • _artist adalah artis yang ingin kita cari
  • _finalUrl adalah URL final dan sepenuhnya dibuat yang akan kita buat panggilan ke iTunes
  • makeUrl adalah fungsi yang akan membuat dan mengembalikan URL ramah iTunes kami.

Sekarang setelah variabel dan fungsi pembantu / pribadi kami ada, mari tambahkan beberapa properti ke objek ‘layanan’. Apa pun yang kami berikan pada 'layanan' dapat langsung digunakan di dalam controller mana pun yang kami lewati 'myFactory' menjadi.

Kami akan membuat metode setArtist dan getArtist yang hanya mengembalikan atau mengatur artis. Kami juga akan membuat metode yang akan memanggil API iTunes dengan URL yang kami buat. Metode ini akan mengembalikan janji yang akan dipenuhi setelah data kembali dari API iTunes. Jika Anda belum memiliki banyak pengalaman menggunakan janji di AngularJS, saya sangat menyarankan untuk melakukan penyelaman mendalam pada mereka.

Di bawah setArtist menerima artis dan memungkinkan Anda untuk mengatur artis. getArtist mengembalikan artis. callItunes panggilan pertama makeUrl () untuk membangun URL yang akan kita gunakan dengan permintaan $ http kami. Kemudian ia membuat objek janji, membuat permintaan $ http dengan url final kami, kemudian karena $ http mengembalikan janji, kami dapat memanggil .success atau .error setelah permintaan kami. Kami kemudian menyelesaikan janji kami dengan data iTunes, atau kami menolaknya dengan pesan yang mengatakan 'Ada kesalahan'.

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;
});

Sekarang pabrik kami selesai. Kami sekarang dapat menyuntikkan ‘myFactory’ ke pengontrol apa pun dan kemudian kami akan dapat memanggil metode kami yang kami lampirkan ke objek layanan kami (setArtist, getArtist, dan 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);
      })
  }
});

Di pengontrol di atas, kami sedang menyuntikkan di layanan ‘myFactory’. Kami kemudian mengatur properti pada objek lingkup $ kami dengan data dari ‘myFactory’. Satu-satunya kode rumit di atas adalah jika Anda belum pernah berurusan dengan janji sebelumnya. Karena callItunes mengembalikan sebuah janji, kita dapat menggunakan metode .then () dan hanya mengatur $ scope.data.artistData setelah janji kita dipenuhi dengan data iTunes. Anda akan melihat pengontrol kami sangat 'tipis' (Ini adalah praktik pengkodean yang bagus). Semua data logika dan persisten kami terletak di layanan kami, bukan di controller kami.

2) Layanan 
Mungkin hal terbesar yang perlu diketahui ketika berhadapan dengan membuat Layanan adalah bahwa itu dibuat dengan kata kunci 'baru'. Bagi Anda guru JavaScript ini seharusnya memberi Anda petunjuk besar tentang sifat kode. Bagi Anda dengan latar belakang terbatas dalam JavaScript atau bagi mereka yang tidak terlalu akrab dengan apa yang kata kunci ‘baru’ sebenarnya, mari kita tinjau beberapa dasar-dasar JavaScript yang pada akhirnya akan membantu kami memahami sifat Layanan.

Untuk benar-benar melihat perubahan yang terjadi ketika Anda menjalankan fungsi dengan kata kunci ‘baru’, mari buat fungsi dan aktifkan dengan kata kunci ‘baru’, lalu mari kita tunjukkan apa yang dilakukan juru bahasa ketika melihat kata kunci ‘baru’. Hasil akhir keduanya akan sama.

Pertama mari buat Pembuatnya.

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

Ini adalah fungsi konstruktor JavaScript yang umum. Sekarang setiap kali kita memanggil fungsi Person menggunakan kata kunci 'baru', 'ini' akan terikat ke objek yang baru dibuat.

Sekarang mari tambahkan metode ke prototipe Person kami sehingga akan tersedia di setiap instance 'kelas' Person kami.

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

Sekarang, karena kami menempatkan fungsi sayName pada prototipe, setiap instance Orang akan dapat memanggil fungsi sayName dalam rangka memperingatkan nama instance itu.

Sekarang setelah kita memiliki fungsi konstruktor Person dan fungsi sayName pada prototipenya, mari kita membuat sebuah instance dari Person kemudian memanggil fungsi sayName.

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

Jadi bersama-sama kode untuk membuat konstruktor Person, menambahkan fungsi ke prototipe, membuat instance Person, dan kemudian memanggil fungsi pada prototipe tampilannya seperti ini.

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’

Sekarang mari kita lihat apa yang sebenarnya terjadi ketika Anda menggunakan kata kunci ‘baru’ di JavaScript. Hal pertama yang harus Anda perhatikan adalah bahwa setelah menggunakan ‘baru’ dalam contoh kami, kami dapat memanggil metode (sayName) di ‘tyler’ seolah-olah itu adalah objek - itu karena itu. Jadi pertama, kita tahu bahwa konstruktor Person kita mengembalikan objek, apakah kita dapat melihat itu dalam kode atau tidak. Kedua, kita tahu bahwa karena fungsi sayName kami terletak pada prototipe dan tidak langsung pada instance Person, objek yang dikembalikan fungsi Person harus mendelegasikan ke prototipe pada pencarian gagal. Dalam istilah yang lebih sederhana, ketika kita memanggil tyler.sayName () penerjemah mengatakan, “Oke, saya akan melihat objek‘ tyler ’yang baru saja kita buat, mencari fungsi sayName, lalu memanggilnya. Tunggu sebentar, saya tidak melihatnya di sini - yang saya lihat hanyalah nama dan usia, biarkan saya memeriksa prototipe. Yup, sepertinya itu ada di prototipe, biarkan saya menyebutnya. ”.

Di bawah ini adalah kode untuk bagaimana Anda dapat berpikir tentang apa yang sebenarnya dilakukan oleh kata kunci 'baru' di JavaScript. Pada dasarnya ini adalah contoh kode dari paragraf di atas. Saya telah menempatkan ‘tampilan juru bahasa’ atau cara penerjemah melihat kode di dalam catatan.

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;
}

Sekarang memiliki pengetahuan tentang apa yang kata kunci 'baru' benar-benar dilakukan di JavaScript, membuat Layanan di AngularJS seharusnya lebih mudah dipahami.

Hal terbesar yang harus dipahami saat membuat Layanan adalah mengetahui bahwa Layanan dibuat dengan kata kunci 'baru'. Dengan menggabungkan pengetahuan tersebut dengan contoh-contoh kami di atas, Anda sekarang harus menyadari bahwa Anda akan melampirkan properti dan metode Anda langsung ke 'ini' yang kemudian akan dikembalikan dari Layanan itu sendiri. Mari kita lihat ini dalam aksi.

Tidak seperti apa yang awalnya kita lakukan dengan contoh Pabrik, kita tidak perlu membuat objek kemudian mengembalikan objek itu karena, seperti disebutkan berkali-kali sebelumnya, kami menggunakan kata kunci 'baru' sehingga penerjemah akan membuat objek itu, mendelegasikannya ke itu prototipe, lalu kembalikan untuk kita tanpa kita harus melakukan pekerjaan.

Pertama-tama, mari kita ciptakan fungsi 'pribadi' dan pembantu kami. Ini akan terlihat sangat akrab karena kami melakukan hal yang sama persis dengan pabrik kami. Saya tidak akan menjelaskan apa yang dilakukan setiap baris di sini karena saya melakukan itu di pabrik contoh, jika Anda bingung, baca kembali contoh pabrik.

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;
  }
});

Sekarang, kami akan melampirkan semua metode kami yang akan tersedia di pengontrol kami untuk ‘ini’.

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;
  }

});

Sekarang seperti di pabrik kami, setArtist, getArtist, dan callItunes akan tersedia di controller mana pun yang kami lewati myService. Berikut pengontrol myService (yang hampir persis sama dengan pengontrol pabrik kami).

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);
      })
  }
});

Seperti yang saya sebutkan sebelumnya, setelah Anda benar-benar memahami apa yang 'baru', Layanan hampir identik dengan pabrik di AngularJS.

3) Penyedia

Hal terbesar yang perlu diingat tentang Penyedia adalah bahwa mereka adalah satu-satunya layanan yang dapat Anda lewati ke dalam bagian aplikasi.config dari aplikasi Anda. Ini sangat penting jika Anda perlu mengubah beberapa bagian dari objek layanan Anda sebelum tersedia di tempat lain di aplikasi Anda. Meskipun sangat mirip dengan Layanan / Pabrik, ada beberapa perbedaan yang akan kita diskusikan.

Pertama kami menyiapkan Penyedia kami dengan cara yang sama seperti yang kami lakukan dengan Layanan dan Pabrik kami. Variabel di bawah ini adalah fungsi 'pribadi' dan pembantu kami.

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;
  }
}

* Sekali lagi jika ada bagian dari kode di atas yang membingungkan, periksa bagian Pabrik tempat saya menjelaskan apa yang semuanya lakukan dengan detail yang lebih besar.

Anda dapat menganggap Penyedia memiliki tiga bagian. Bagian pertama adalah variabel / fungsi 'pribadi' yang akan dimodifikasi / disetel nanti (ditunjukkan di atas). Bagian kedua adalah variabel / fungsi yang akan tersedia di fungsi app.config Anda dan oleh karena itu tersedia untuk diubah sebelum tersedia di tempat lain (juga ditampilkan di atas). Penting untuk diperhatikan bahwa variabel tersebut harus dilampirkan pada kata kunci 'ini'. Dalam contoh kami, hanya 'thingFromConfig' yang akan tersedia untuk diubah di app.config. Bagian ketiga (diperlihatkan di bawah) adalah semua variabel / fungsi yang akan tersedia di pengontrol Anda saat Anda meneruskan layanan ‘myProvider’ ke pengontrol khusus tersebut.

Saat membuat layanan dengan Penyedia, satu-satunya properti / metode yang akan tersedia di pengontrol Anda adalah properti / metode yang dikembalikan dari fungsi $ get (). Kode di bawah ini menempatkan $ get pada 'ini' (yang kami tahu akhirnya akan dikembalikan dari fungsi itu). Sekarang, fungsi $ get mengembalikan semua metode / properti yang kita inginkan tersedia di controller. Berikut contoh kode.

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
    }
  }

Sekarang kode Provider lengkap terlihat seperti ini

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
    }
  }
});

Sekarang seperti di pabrik dan Layanan kami, setArtist, getArtist, dan callItunes akan tersedia di mana pun pengendali yang kami lewati myProvider. Berikut pengontrol myProvider (yang hampir persis sama dengan pengontrol pabrik / Layanan kami).

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;
});

Seperti yang disebutkan sebelumnya, seluruh titik pembuatan layanan dengan Penyedia adalah untuk dapat mengubah beberapa variabel melalui fungsi app.config sebelum objek akhir diteruskan ke seluruh aplikasi. Mari kita lihat contohnya.

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';
});

Sekarang Anda dapat melihat bagaimana 'thingFromConfig' sebagai string kosong di penyedia kami, tetapi ketika itu muncul di DOM, itu akan menjadi 'Kalimat ini telah ditetapkan ...'.


618
2017-12-24 13:15



Semua Layanan lajang; mereka mendapatkan instantiated satu kali per aplikasi. Mereka bisa menjadi jenis apa pun, apakah itu primitif, objek literal, fungsi, atau bahkan sebuah instance dari tipe kustom.

Itu value, factory, service, constant, dan provider metode semua penyedia. Mereka mengajarkan Injector bagaimana memberi contoh Layanan.

Yang paling verbose, tetapi juga yang paling komprehensif adalah Provider   resep. Itu tersisa empat jenis resep - Nilai, Pabrik, Layanan, dan   Konstan - hanya gula sintaksis di atas resep penyedia.

  • Itu Nilai Resep adalah kasus yang paling sederhana, di mana Anda memberi Instan Layanan sendiri dan memberikan nilai instantiated ke injektor.
  • Itu Resep pabrik memberi Injector fungsi pabrik yang dipanggilnya ketika perlu memberi contoh layanan. Saat dipanggil, fungsi pabrik membuat dan mengembalikan instance layanan. Dependensi Layanan disuntikkan sebagai argumen fungsi. Jadi menggunakan resep ini menambahkan kemampuan berikut:
    • Kemampuan untuk menggunakan layanan lain (memiliki ketergantungan)
    • Inisialisasi layanan
    • Inisialisasi yang tertunda / malas
  • Itu Resep layanan hampir sama dengan resep Pabrik, tapi di sini Injector memanggil a konstruktor dengan operator baru alih-alih fungsi pabrik.
  • Itu Resep penyedia biasanya berlebihan. Ini menambahkan satu lagi lapisan tipuan dengan memungkinkan Anda mengkonfigurasi pembuatan pabrik.

Anda harus menggunakan resep Penyedia hanya ketika Anda ingin mengekspos API   untuk konfigurasi seluruh aplikasi yang harus dibuat sebelum   aplikasi dimulai. Ini biasanya menarik hanya untuk dapat digunakan kembali   layanan yang perilakunya mungkin perlu sedikit berbeda   aplikasi.


506
2018-02-01 12:58



Memahami Pabrik, Layanan dan Penyedia AngularJS

Semua ini digunakan untuk berbagi benda tunggal yang dapat digunakan kembali. Ini membantu untuk membagikan kode yang dapat digunakan kembali di aplikasi Anda / berbagai komponen / modul.

Dari Dokumen Layanan / Pabrik:

  • Diperanakan Lazily - Angular hanya instantiates service / pabrik ketika komponen aplikasi tergantung padanya.
  • Singletons - Setiap komponen   tergantung pada layanan mendapat referensi ke contoh tunggal   dihasilkan oleh pabrik layanan.

Pabrik

Pabrik adalah fungsi tempat Anda dapat memanipulasi / menambahkan logika sebelum membuat objek, lalu objek yang baru dibuat akan dikembalikan.

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

Pemakaian

Itu bisa hanya kumpulan fungsi seperti kelas. Oleh karena itu, dapat dipakai dalam pengendali yang berbeda ketika Anda menyuntikkannya di dalam fungsi controller / pabrik / direktif Anda. Ini hanya dipakai sekali per aplikasi.

Layanan

Cukup sambil melihat layanan berpikir tentang prototipe array. Layanan adalah fungsi yang menginstansi objek baru menggunakan kata kunci 'baru'. Anda dapat menambahkan properti dan fungsi ke objek layanan dengan menggunakan thiskata kunci. Tidak seperti pabrik, ia tidak mengembalikan apa pun (mengembalikan suatu objek yang berisi metode / properti).

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

Pemakaian

Gunakan saat Anda perlu berbagi satu objek di seluruh aplikasi. Misalnya, rincian pengguna yang diautentikasi, metode / data yang dapat dibagikan, fungsi Utility, dll.

Pemberi

Penyedia digunakan untuk membuat objek layanan yang dapat dikonfigurasi. Anda dapat mengkonfigurasi pengaturan layanan dari fungsi konfigurasi. Ini mengembalikan nilai dengan menggunakan $get() fungsi. Itu $get fungsi dijalankan pada fase run dalam bentuk sudut.

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.
        };
    };
});

Pemakaian

Ketika Anda perlu menyediakan konfigurasi modul-bijaksana untuk objek layanan Anda sebelum membuatnya tersedia, misalnya. misalkan Anda ingin mengatur URL API Anda atas dasar Lingkungan Anda seperti dev, stage atau prod

CATATAN 

Hanya penyedia akan tersedia dalam fase konfigurasi sudut, sementara   layanan & pabrik tidak.

Semoga ini telah membereskan pemahaman Anda tentang Pabrik, Layanan, dan Penyedia.


221
2017-11-14 06:25



Bagi saya, wahyu datang ketika saya menyadari bahwa mereka semua bekerja dengan cara yang sama: dengan menjalankan sesuatu sekali, menyimpan nilai yang mereka dapatkan, dan kemudian batuk nilai tersimpan yang sama ketika direferensikan melalui injeksi ketergantungan.

Katakanlah kita memiliki:

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

Perbedaan antara ketiganya adalah bahwa:

  1. aNilai tersimpan berasal dari berlari fn.
  2. bDari nilai tersimpan berasal newing fn.
  3. cDisimpan nilai berasal dari pertama mendapatkan sebuah instance oleh newing fn, lalu jalankan a $get metode instance.

Artinya ada sesuatu seperti objek cache di dalam AngularJS, yang nilainya setiap injeksi hanya ditetapkan satu kali, ketika mereka disuntikkan pertama kali, dan di mana:

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

Inilah mengapa kami menggunakannya this dalam layanan, dan menentukan a this.$get dalam penyedia.


190
2017-07-22 11:39



Layanan vs penyedia vs pabrik:

Saya mencoba membuatnya sederhana. Ini semua tentang konsep JavaScript dasar.

Pertama-tama, mari kita bicarakan jasa di AngularJS!

Apa itu Layanan: Di AngularJS, Layanan tidak lain adalah objek JavaScript tunggal yang dapat menyimpan beberapa metode atau properti yang bermanfaat. Objek tunggal ini dibuat per ngApp (aplikasi Angular) dan dibagi di antara semua pengontrol dalam aplikasi saat ini. Ketika Angularjs memberi contoh objek layanan, Anglo akan mendaftarkan objek layanan ini dengan nama layanan unik. Jadi setiap kali ketika kita membutuhkan contoh layanan, Cari sudut registri untuk nama layanan ini, dan mengembalikan referensi ke objek layanan. Sehingga kita dapat memanggil metode, mengakses properti dll pada objek layanan. Anda mungkin memiliki pertanyaan apakah Anda juga dapat menempatkan properti, metode pada objek lingkup pengendali! Jadi mengapa Anda membutuhkan objek layanan? Jawabannya adalah: layanan dibagi di antara beberapa lingkup pengontrol. Jika Anda meletakkan beberapa properti / metode dalam objek lingkup pengontrol, itu akan tersedia untuk lingkup saat ini saja. Tetapi ketika Anda mendefinisikan metode, properti pada objek layanan, itu akan tersedia secara global dan dapat diakses dalam lingkup pengontrol apa pun dengan menyuntikkan layanan itu.

Jadi jika ada tiga bidang pengontrol, biar saja controllerA, controllerB dan controllerC, semua akan berbagi instance layanan yang sama.

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

Bagaimana cara membuat layanan?

AngularJS menyediakan metode berbeda untuk mendaftarkan layanan. Di sini kita akan berkonsentrasi pada tiga metode pabrik (..), service (..), provider (..);

Gunakan tautan ini untuk referensi kode

Fungsi pabrik:

Kita dapat mendefinisikan fungsi pabrik seperti di bawah ini.

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

AngularJS menyediakan 'pabrik (' serviceName ', fnFactory)' metode yang mengambil dua parameter, serviceName dan fungsi JavaScript. Sudut menciptakan contoh layanan dengan menjalankan fungsi fnFactory () seperti di bawah ini.

var serviceInstace = fnFactory();

Fungsi yang diteruskan dapat menentukan objek dan mengembalikan objek itu. AngularJS hanya menyimpan referensi objek ini ke variabel yang dilewatkan sebagai argumen pertama. Apa pun yang dikembalikan dari fnFactory akan terikat dengan serviceInstance. Alih-alih mengembalikan objek, kita juga dapat mengembalikan fungsi, nilai, dll. Apa pun yang akan kita kembalikan, akan tersedia untuk instance layanan.

Contoh:

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;
});

Fungsi Layanan:

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

Ini cara lain, kita bisa mendaftarkan layanan. Satu-satunya perbedaan adalah cara AngularJS mencoba menginstansiasikan objek layanan. Kali ini sudut menggunakan kata kunci 'baru' dan memanggil fungsi konstruktor seperti di bawah ini.

var serviceInstance = new fnServiceConstructor();

Dalam fungsi konstruktor kita dapat menggunakan kata kunci 'ini' untuk menambahkan properti / metode ke objek layanan. contoh:

//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);
  };
});

Fungsi penyedia:

Fungsi Provider () adalah cara lain untuk membuat layanan. Mari kita tertarik untuk membuat layanan yang hanya menampilkan beberapa pesan ucapan kepada pengguna. Tetapi kami juga ingin menyediakan fungsionalitas sehingga pengguna dapat mengatur pesan sambutan mereka sendiri. Dalam istilah teknis kami ingin membuat layanan yang dapat dikonfigurasi. Bagaimana kami bisa melakukan ini? Harus ada jalan, sehingga aplikasi dapat meneruskan pesan ucapan khusus dan Angularjs akan membuatnya tersedia untuk fungsi pabrik / konstruktor yang membuat instance layanan kami. Dalam kasus seperti penyedia () fungsi melakukan pekerjaan. menggunakan provider () fungsi kita dapat membuat layanan yang dapat dikonfigurasi.

Kita dapat membuat layanan yang dapat dikonfigurasi menggunakan sintaks penyedia seperti yang diberikan di bawah ini.

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

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

Bagaimana sintaks penyedia bekerja secara internal?

1.Provider objek dibuat menggunakan fungsi konstruktor yang kami definisikan dalam fungsi provider kami.

var serviceProvider = new serviceProviderConstructor();

2.Fungsi yang kami lewati di app.config (), dieksekusi. Ini disebut fase config, dan di sini kami memiliki kesempatan untuk menyesuaikan layanan kami.

configureService(serviceProvider);

3.Finally service instance dibuat dengan memanggil $ get method of serviceProvider.

serviceInstance = serviceProvider.$get()

Kode contoh untuk membuat layanan menggunakan menyediakan sintaks:

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 Kerja

Ringkasan:


Pabrik menggunakan fungsi pabrik yang mengembalikan instance layanan. serviceInstance = fnFactory ();

Layanan menggunakan fungsi konstruktor dan Angular memohon fungsi konstruktor ini menggunakan kata kunci 'baru' untuk membuat instance layanan. serviceInstance = new fnServiceConstructor ();

Pemberi mendefinisikan fungsi providerConstructor, fungsi providerConstructor ini mendefinisikan fungsi pabrik $ get . Angular memanggil $ get () untuk membuat objek layanan. Sintaks penyedia memiliki keuntungan tambahan untuk mengonfigurasi objek layanan sebelum mendapatkan instantiated. serviceInstance = $ get ();


133
2017-11-19 13:36



Seperti yang ditunjukkan oleh beberapa orang di sini dengan benar, pabrik, penyedia, layanan, dan bahkan nilai dan konstan adalah versi dari hal yang sama. Anda bisa membedah yang lebih umum provider ke semua dari mereka. Seperti ini:

enter image description here

Inilah artikel gambar ini dari:

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


79
2017-08-02 05:37



Pabrik

Anda memberikan fungsi AngularJS, AngularJS akan menyimpan dan menyuntikkan nilai pengembalian ketika pabrik diminta.

Contoh:

app.factory('factory', function() {
    var name = '';
    // Return value **is** the object that will be injected
    return {
        name: name;
    }
})

Pemakaian:

app.controller('ctrl', function($scope, factory) {
     $scope.name = factory.name;
});

Layanan

Anda memberikan fungsi AngularJS, AngularJS akan menelepon baru untuk instantiate itu. Ini adalah contoh yang dibuat AngularJS yang akan di-cache dan disuntikkan ketika layanan diminta. Sejak baru digunakan untuk memberi contoh layanan, kata kunci ini valid dan mengacu pada instance.

Contoh:

app.service('service', function() {
     var name = '';
     this.setName = function(newName) {
         name = newName;
     }
     this.getName = function() {
         return name;
     }
});

Pemakaian:

app.controller('ctrl', function($scope, service) {
   $scope.name = service.getName();
});

Pemberi

Anda memberi AngularJS fungsi, dan AngularJS akan memanggilnya $get fungsi. Ini adalah nilai kembalian dari $get fungsi yang akan di-cache dan disuntikkan ketika layanan diminta.

Penyedia memungkinkan Anda untuk mengonfigurasi penyedia sebelum AngularJS memanggil $get metode untuk mendapatkan suntikan.

Contoh:

app.provider('provider', function() {
     var name = '';
     this.setName = function(newName) {
          name = newName;
     }
     this.$get = function() {
         return {
            name: name
         }
     }
})

Penggunaan (sebagai suntik dalam pengontrol)

app.controller('ctrl', function($scope, provider) {
    $scope.name = provider.name;
});

Penggunaan (mengkonfigurasi penyedia sebelumnya $get dipanggil untuk membuat suntikan)

app.config(function(providerProvider) {
    providerProvider.setName('John');
});

62
2018-05-19 19:53



Saya melihat sesuatu yang menarik saat bermain-main dengan penyedia.

Visibilitas suntikan berbeda untuk penyedia daripada untuk layanan dan pabrik. Jika Anda menyatakan "konstanta" AngularJS (misalnya, myApp.constant('a', 'Robert');), Anda dapat menyuntikkannya ke layanan, pabrik, dan penyedia.

Tetapi jika Anda menyatakan "nilai" AngularJS (misalnya., myApp.value('b', {name: 'Jones'});), Anda dapat menyuntikkannya ke dalam layanan dan pabrik, tetapi TIDAK ke fungsi penyedia-penyedia. Anda bisa, bagaimanapun, menyuntikkannya ke dalam $get fungsi yang Anda tetapkan untuk penyedia Anda. Ini disebutkan dalam dokumentasi AngularJS, tetapi mudah untuk dilewatkan. Anda dapat menemukannya di halaman menyediakan% di bagian pada nilai dan metode konstan.

http://jsfiddle.net/R2Frv/1/

<div ng-app="MyAppName">
    <div ng-controller="MyCtrl">
        <p>from Service: {{servGreet}}</p>
        <p>from Provider: {{provGreet}}</p>
    </div>
</div>
<script>
    var myApp = angular.module('MyAppName', []);

    myApp.constant('a', 'Robert');
    myApp.value('b', {name: 'Jones'});

    myApp.service('greetService', function(a,b) {
        this.greeter = 'Hi there, ' + a + ' ' + b.name;
    });

    myApp.provider('greetProvider', function(a) {
        this.firstName = a;
        this.$get = function(b) {
            this.lastName = b.name;
            this.fullName = this.firstName + ' ' + this.lastName;
            return this;
        };
    });

    function MyCtrl($scope, greetService, greetProvider) {
        $scope.servGreet = greetService.greeter;
        $scope.provGreet = greetProvider.fullName;
    }
</script>

54
2017-10-09 03:43



Ini adalah bagian yang sangat membingungkan bagi pemula dan saya telah mencoba menjelaskannya dengan kata-kata yang mudah

Layanan AngularJS: digunakan untuk berbagi fungsi utilitas dengan referensi layanan di controller. Layanan bersifat tunggal sehingga untuk satu layanan hanya satu contoh yang dibuat di browser dan referensi yang sama digunakan di seluruh halaman.

Di layanan, kami membuat nama fungsi sebagai properti dengan ini obyek.

Pabrik AngularJS: tujuan Factory juga sama dengan Service, tetapi dalam hal ini kita membuat objek baru dan menambahkan fungsi sebagai properti dari objek ini dan pada akhirnya kita mengembalikan objek ini.

Penyedia AngularJS: tujuan ini lagi sama namun Provider memberikan output dari fungsi $ get.

Mendefinisikan dan menggunakan Layanan, Pabrik dan Penyedia dijelaskan di http://www.dotnetfunda.com/articles/show/3156/difference-between-angularjs-service-factory-and-provider 


43
2018-04-30 11:20