2016-03-03 7 views
7

मैं एक आधार सेवा है जो इस तरह दिखता है:AngularJS सेवा विरासत मुद्दों

.service('BaseImageService', ['$q', 'ApiHandler', 'UploadService', function ($q, api, uploadService) { 

    // Get our api path 
    var apiPath = 'logos'; 

    // Creates our logo 
    var _createLogo = function (model) { 

     // Handle our uploads 
     return _handleUploads(model).then(function() { 

      // Create our logo 
      return api.post(apiPath, model); 
     }); 
    }; 

    // Edit our logo 
    var _editLogo = function (model) { 

     // Handle our uploads 
     return _handleUploads(model).then(function() { 

      // Create our logo 
      return api.put(apiPath, model); 
     }); 
    }; 

    // Handles our files 
    var _handleUploads = function (model) { 

     // Create a promises array 
     var promises = []; 

     // Get our file 
     var file = model.file, 
      old = model.old; 

     // If we have a file 
     if (file) { 

      // Try to upload the file 
      promises.push(uploadService.upload(model.file).then(function (response) { 

       // Update our model 
       model.path = response.path; 
       model.thumbnail = response.thumbnail; 
      })); 

      // If we have an old model 
      if (old) { 

       // Delete both our files 
       promises.push(uploadService.delete(old.path)); 
       promises.push(uploadService.delete(old.thumbnail)); 
      } 
     } 

     // After all promises have completed 
     return $q.all(promises); 
    }; 

    // Create our service 
    var service = { 

     // Update our api path 
     updateApiPath: function (path) { 

      // Set the api path 
      apiPath = path; 
     }, 

     // Gets a list of logos 
     list: function (t) { 

      if (t) { 
       console.log(apiPath); 
      } 

      // Get our logo 
      return api.get(apiPath); 
     }, 

     // Get a single logo 
     get: function (id) { 

      // Get our logo 
      return api.get(apiPath, { id: id }); 
     }, 

     // Create our logo 
     save: function (model) { 

      // If we are editing 
      if (model.id) { 

       // Edit our logo 
       return _editLogo(model); 

       // If we are creating 
      } else { 

       // Create our logo 
       return _createLogo(model); 
      } 
     }, 

     // Deletes our logo 
     delete: function (id) { 

      // Delete our logo 
      return api.delete(apiPath, { id: id }); 
     }, 

     // Prepare for editing 
     prepareForEditing: function (model) { 

      // Create our old object 
      model.old = { 
       path: model.path, 
       thumbnail: model.thumbnail 
      }; 
     } 
    }; 

    // Return our service 
    return service; 
}]) 

और उसके बाद मैं कुछ सेवाओं है जो "वारिस" इस सेवा, इस तरह:

.service('ImageService', ['BaseImageService', function (baseService) { 

    // Get our api path 
    var apiPath = 'images'; 

    // Update the apiPath 
    baseService.updateApiPath(apiPath); 

    // Return our service 
    return baseService; 
}]) 

.service('LogoService', ['BaseImageService', function (baseService) { 

    // Get our api path 
    var apiPath = 'logos'; 

    // Update the apiPath 
    baseService.updateApiPath(apiPath); 

    // Return our service 
    return baseService; 
}]) 

.service('PlayerTextService', ['BaseImageService', function (baseService) { 

    // Get our api path 
    var apiPath = 'playerText'; 

    // Update the apiPath 
    baseService.updateApiPath(apiPath); 

    // Return our service 
    return baseService; 
}]) 

मैंने सोचा यह ठीक काम कर रहा था। लेकिन मेरे पास यह पृष्ठ है जो अनुक्रमिक रूप से सभी 3 सेवाओं (छवि सेवा, लोगो सेवा और प्लेयरटेक्स्ट सेवा) को कॉल करता है। पृष्ठ के पहले दृश्य पर सब ठीक है, अगर मैं दूर नेविगेट करता हूं और फिर वापस आ जाता है तो छवि सेवा वास्तव में प्लेयर टेक्स्ट सेवा से वापस खींचती है। अब मुझे पता है कि यह सिंगलटन होने की वजह से है, लेकिन मुझे यकीन नहीं है कि मेरी समस्या को कैसे ठीक किया जाए।

क्या कोई मुझे हाथ दे सकता है?


मैं किसी प्रयास किए गए समाधान के साथ एक codepen जोड़ लिया है:

http://codepen.io/r3plica/pen/ONVBJO


प्रयास 2

http://codepen.io/r3plica/pen/jqPeMQ?editors=1010

+0

आप कारखानों का निर्माण कर रहे 'service' और प्रत्येक सेवा baseService वापस नहीं जाना चाहिए। नहीं वास्तव में स्पष्ट आप वास्तविक 'service' जो' का उपयोग कर this' सदस्यों के लिए ... तो वापसी 'अन्य कारखानों आप – charlietfl

+0

Convert आधार करने के लिए कोशिश कर रहे हैं एक उदाहरण के रूप codepen ? – charlietfl

+0

आप संशोधित कर सकते है से नए baseService' एक निर्माता है – r3plica

उत्तर

2

चारों ओर खिलवाड़ का एक बहुत बाद;

.factory('BaseImageService', ['$q', 'ApiHandler', 'UploadService', 'vectorExtensions', function ($q, api, uploadService, vectorExtensions) { 

    // Creates our logo 
    var _createLogo = function (model) { 

     // Handle our uploads 
     return _handleUploads(model).then(function() { 

      // Create our logo 
      return api.post(BaseImageService.apiPath, model); 
     }); 
    }; 

    // Edit our logo 
    var _editLogo = function (model) { 

     // Handle our uploads 
     return _handleUploads(model).then(function() { 

      // Create our logo 
      return api.put(BaseImageService.apiPath, model); 
     }); 
    }; 

    // Handles our files 
    var _handleUploads = function (model) { 

     // Create a promises array 
     var promises = []; 

     // Get our file 
     var file = model.file, 
      old = model.old; 

     // If we have a file 
     if (file) { 

      // Try to upload the file 
      promises.push(uploadService.upload(model.file).then(function (response) { 

       // Update our model 
       model.path = response.path; 
       model.thumbnail = response.thumbnail; 
       model.fileName = response.fileName; 
      })); 

      // If we have an old model 
      if (old) { 

       // Delete both our files 
       promises.push(uploadService.delete(old.path)); 
       promises.push(uploadService.delete(old.thumbnail)); 
      } 
     } 

     // After all promises have completed 
     return $q.all(promises); 
    }; 

    // Addes a property to the image array to state if they are vector images or not 
    var _addVectorProperties = function (images) { 

     // Loop through our images 
     for (var i = 0; i < images.length; i++) { 

      // Get our current image 
      var image = _addVectorProperty(images[i]); 
     } 

     // Return our images 
     return images; 
    }; 

    // Adds a property to the image to state if it is vector or not 
    var _addVectorProperty = function (image) { 

     // Vector flag 
     var vector = false; 

     // Get our file extension 
     var parts = image.path.split('.'); 

     // If we have any parts 
     if (parts.length) { 

      // Get our last part 
      var ext = parts[parts.length - 1], 
       index = vectorExtensions.indexOf(ext); 

      // If our extension exists in our vector array 
      if (index > -1) { 

       // Change our vector property 
       vector = true; 
      } 
     } 

     // Update our image with the new property 
     image.vector = vector; 

     // Return our image 
     return image; 
    }; 

    // Create our service 
    var BaseImageService = function (path) { 

     // Set our apiPath 
     this.apiPath = path; 

     // Update our api path 
     this.updateApiPath = function (path) { 

      // Set the api path 
      apiPath = path; 
     }; 

     // Gets a list of logos 
     this.list = function() { 

      // Get our logo 
      return api.get(this.apiPath).then(_addVectorProperties); 
     }; 

     // Get a single logo 
     this.get = function (id) { 

      // Get our logo 
      return api.get(this.apiPath, { id: id }).then(_addVectorProperty); 
     }; 

     // Create our logo 
     this.save = function (model) { 

      // If we are editing 
      if (model.id) { 

       // Edit our logo 
       return _editLogo(model); 

       // If we are creating 
      } else { 

       // Create our logo 
       return _createLogo(model); 
      } 
     }; 

     // Deletes our logo 
     this.delete = function (id) { 

      // Delete our logo 
      return api.delete(this.apiPath, { id: id }); 
     }; 

     // Set our active image 
     this.setActive = function (images, image) { 

      // Loop through our images 
      for (var i = 0; i < images.length; i++) { 

       // Get our current image 
       var current = images[i]; 

       // Set whether we are active or not 
       current.active = image.id === current.id ? true : false; 
      } 
     }; 

     // Prepare for editing 
     this.prepareForEditing = function (model) { 

      // Create our old object 
      model.old = { 
       path: model.path, 
       thumbnail: model.thumbnail 
      }; 
     }; 
    }; 

    // Return our service 
    return BaseImageService; 
}]) 

और बच्चे सेवाओं इस तरह दिखेगा:

.service('ImageService', ['BaseImageService', function (baseService) { 

    // Create our base service 
    var child = new baseService('images'); 

    // Return our new service 
    return child; 
}]) 

.service('LogoService', ['BaseImageService', function (baseService) { 

    // Create our base service 
    var child = new baseService('logos'); 

    // Return our new service 
    return child; 
}]) 

.service('PlayerTextService', ['BaseImageService', function (baseService) { 

    // Create our base service 
    var child = new baseService('playerText'); 

    // Return our new service 
    return child; 
}]) 

कि ठीक काम करता है मैं अंत में एक समाधान adapting this bit of code

मेरे आधार सेवा इस तरह दिखता है पाया।

+0

का उपयोग करके अपनी किसी भी फ़ाइल से पहले प्रासंगिक जावास्क्रिप्ट फ़ाइल को शामिल करना होगा। इस संस्करण के साथ आप किसी भी तरह निर्भरता इंजेक्शन तंत्र को बहुत अधिक बनाते हैं अपने नियंत्रकों का परीक्षण करना कठिन है क्योंकि आप अब परीक्षण निष्पादन के दौरान कुछ संशोधित "बाल सेवा" को इंजेक्ट करने में सक्षम नहीं हैं ... (केवल तभी जब आप पूरी अभिभावक सेवा का मज़ाक उड़ाते हैं) –

2

समाधान करने की कोशिश की काम नहीं करता हैक्योंकि बेस सर्विस एक सिंगलटन है। तो आप सभी तीन सेवा पंजीकरण कार्यों में बिल्कुल वही उदाहरण इंजेक्ट करते हैं और उनमें से सभी एक ही ऑब्जेक्ट को कॉन्फ़िगर करते हैं। तो मूल रूप से आखिरी जीतता है।

ऐसा लगता है कि आप अलग-अलग कॉन्फ़िगरेशन के साथ अलग-अलग सेवाएं चाहते हैं। यही प्रदाताओं का उपयोग किया जाता है। वे सेवा उदाहरण बनाने की दो-चरणीय प्रक्रिया की अनुमति देते हैं। कृपया विषय पर इस महान Stackoverflow जवाब देखें:

AngularJS: Service vs provider vs factory

संदर्भ के लिए, Restangular एक पुस्तकालय ठीक उसी रूप में आप चाहते प्राप्त करने के लिए की जरूरत है। आप एक खाका के रूप में उपयोग करें और देखें कि Restangular इस आवश्यकता को हैंडल कर सकता है: कि इन अवधारणाओं AngularJS 1 पर आधारित होते हैं

https://github.com/mgonto/restangular#how-to-create-a-restangular-service-with-a-different-configuration-from-the-global-one

कृपया ध्यान रखें और आप इस अलग तरह से संभाल करने की जरूरत है जब आप बाद में AngularJS 2 उपयोग करना चाहते हैं पर।

0

हां यह संलग्न है क्योंकि यह सिंगलटन है। यदि आप ऐसा करना चाहते हैं तो आपको विरासत करना होगा।

यहाँ एक कोड है कि मैं का उपयोग करें और कोणीय को संलग्न है:

angular.baseResourceServiceMaker = function(service){ 
    return ['$injector', '$resource', 'TypeService', '$http', '_', 'BackEndpoint', 
     function($injector, $resource,TypeService, $http, _, BackEndpoint){ 

    //skipping not interesting code 
    // sample fields to inherits 
    this.sample = "test"; 
    this.sampleFN = function(){[...]} 
    // THE line that does the magic 
    $injector.invoke(service, this); 
} 

अब उपयोग

.service('MyService',angular.baseResourceServiceMaker(['$http', function($http){ 
    // overriding fields 
    this.sample="inherits"; 
this.sampleFN = function(){[...]} 
}])); 

तो बुनियादी तौर पर हम यहाँ क्या है के समय? एक फ़ंक्शन बेस रिसोर्स सर्विस मेकर जो एक सामान्य विशेष सेवा का प्रतिनिधित्व करता है। $ इंजेक्टर जो सेवा को कॉल करता है जिसे हम तत्काल बनाना चाहते हैं और जेनेरिक सेवा के दायरे को सेट करना चाहते हैं, इसलिए यह बाल वर्ग पर सामान्य वर्ग की तुलना में एक ही संदर्भ से जुड़ जाएगा। जेनेरिक सेवा तत्काल हो जाएगी जितनी बार आप इसे कॉल करते हैं, कोई भ्रमित नहीं।

मैं व्यक्तिगत रूप से एक कस्टम serializer/दिनांक और कुछ अन्य सामान को संभालने से deserializer होने में कुछ बुनियादी तरीकों को परिभाषित करने के कोणीय के संसाधन मॉड्यूल के लिए इस कोड का उपयोग। आपके मामले में baseResourceServiceMaker $ injector.invoke (सेवा, इस) के साथ समाप्त होने के साथ अपने baseImageService हो जाएगा।

संपादित करें: शायद क्लीनर कुछ के साथ एक लिंक मिल गया: AngularJS service inheritance

+0

मैंने आपके द्वारा प्रदान किए गए लिंक में उन सभी की कोशिश की, लेकिन उनमें से कोई भी काम नहीं किया। मैं आपका प्रयास दूंगा और आपको बता दूंगा कि क्या होता है। – r3plica

+0

अगर मैं angular.baseService कर मैं तुम्हें एक codepen या कुछ और कर सकते हैं कि angular.baseService बताते हुए एक त्रुटि एक समारोह – r3plica

+0

नहीं है मिल सकता है? मैं यह सब – r3plica

0

यदि आप का उपयोग (या करने के लिए स्विच) ES6 या टाइपप्रति बहुत आसान हो जाता है।

export class Base { 
    // . . . 
} 
फिर

:

import {app} from '../app'; 
import {Base} from './base'; 

export class Child extends Base { 
    // . . . 
} 

app.service('child', Child); 
0

अपने प्रयास 1 से:

  1. अपने BaseServiceapiPath वैश्विक स्तर पर की तलाश में,
  2. जबकि कोणीय तैयारी कर निर्भरता अपने पिछले निर्भरता ImageService है,
  3. पहले यह डिप्टी तैयार करेगा endency तो यह चरण 2 से list() विधि,
  4. सभी तरीकों से अपने apiPath संदर्भित करेंगे वैश्विक स्तर घोषित मूल्य, यानी apiPath = 'images'; निष्पादित करेंगे

समाधान: BaseService और list() तहत apiPath के सामने this ऑपरेटर का उपयोग करें।

काम कर Plunker

संबंधित मुद्दे