मैं Angular.js में विभिन्न वातावरणों को कैसे कॉन्फ़िगर करूं?


220

आप विभिन्न परिवेशों के लिए कॉन्फ़िगरेशन चर / स्थिरांक कैसे प्रबंधित करते हैं?

यह एक उदाहरण हो सकता है:

मेरे बाकी API पर पहुंच योग्य है localhost:7080/myapi/, लेकिन मेरे मित्र जो Git संस्करण नियंत्रण के तहत एक ही कोड पर काम करते हैं, उनके एपीआई को उनके Tomcat पर तैनात किया गया है localhost:8099/hisapi/

यह मानते हुए कि हमारे पास ऐसा कुछ है:

angular
    .module('app', ['ngResource'])

    .constant('API_END_POINT','<local_end_point>')

    .factory('User', function($resource, API_END_POINT) {
        return $resource(API_END_POINT + 'user');
    });

मैं पर्यावरण के आधार पर एपीआई समापन बिंदु के सही मूल्य को गतिशील रूप से कैसे इंजेक्ट कर सकता हूं?

PHP में मैं आमतौर पर एक config.username.xmlफाइल के साथ इस प्रकार का सामान करता हूं , जो बेसिक कॉन्फिगरेशन फाइल (config.xml) को मर्ज करके यूजर के नाम से पहचानी जाने वाली लोकल इनवायरमेंट कॉन्फिगरेशन फाइल के साथ होता है। लेकिन मुझे नहीं पता कि जावास्क्रिप्ट में इस तरह का प्रबंधन कैसे किया जाए?

जवाबों:


209

मुझे थ्रेड में थोड़ी देर हो गई है, लेकिन अगर आप ग्रंट का उपयोग कर रहे हैं तो मुझे बड़ी सफलता मिली है grunt-ng-constant

ngconstantमेरे रूप के लिए कॉन्फ़िगर अनुभाग Gruntfile.jsऐसा दिखता है

ngconstant: {
  options: {
    name: 'config',
    wrap: '"use strict";\n\n{%= __ngModule %}',
    space: '  '
  },
  development: {
    options: {
      dest: '<%= yeoman.app %>/scripts/config.js'
    },
    constants: {
      ENV: 'development'
    }
  },
  production: {
    options: {
      dest: '<%= yeoman.dist %>/scripts/config.js'
    },
    constants: {
      ENV: 'production'
    }
  }
}

उपयोग करने वाले कार्य ngconstantजैसे दिखते हैं

grunt.registerTask('server', function (target) {
  if (target === 'dist') {
    return grunt.task.run([
      'build',
      'open',
      'connect:dist:keepalive'
    ]);
  }

  grunt.task.run([
    'clean:server',
    'ngconstant:development',
    'concurrent:server',
    'connect:livereload',
    'open',
    'watch'
  ]);
});

grunt.registerTask('build', [
  'clean:dist',
  'ngconstant:production',
  'useminPrepare',
  'concurrent:dist',
  'concat',
  'copy',
  'cdnify',
  'ngmin',
  'cssmin',
  'uglify',
  'rev',
  'usemin'
]);

इसलिए दौड़ने grunt serverसे एक config.jsफाइल app/scripts/बनेगी जो इस तरह दिखती है

"use strict";
angular.module("config", []).constant("ENV", "development");

अंत में, मैं जो कुछ भी मॉड्यूल की आवश्यकता पर निर्भरता की घोषणा:

// the 'config' dependency is generated via grunt
var app = angular.module('myApp', [ 'config' ]);

अब मेरी स्थिरांक जहां आवश्यकता हो वहां निर्भरता इंजेक्ट की जा सकती है। उदाहरण के लिए,

app.controller('MyController', ['ENV', function( ENV ) {
  if( ENV === 'production' ) {
    ...
  }
}]);

10
बल्कि डालने से 'ngconstant:development'में 'serve'यदि आप के तहत घड़ी की config में रख - 'gruntfile'के रूप में tasks: ['ngconstant:development']आप पुनः आरंभ करने की जरूरत नहीं होगी - grunt serveजब आप gruntfile में विकास चर अद्यतन करें।
बिताए गए

10
अपने कॉन्स्टेंट्स को gruntfile.js में जोड़ने के बजाय, आप इस तरह अलग-अलग फाइलों में डाल सकते हैं:package: grunt.file.readJSON('development.json')
Guilhem Soulas

3
ग्रन्ट-एनजी-कॉन्स्टेंट के 0.5 संस्करण में ग्रंटफाइल.जेएस के लिए एक अद्यतन वाक्यविन्यास है: github.com/werk85/grunt-ng-constant/issues/31 । शानदार जवाब, धन्यवाद!
फेरिस

10
जो लोग gulp का उपयोग करते हैं, उनके लिए gulp-ng-constant है
धीरज वेपकोमा

4
मैंने पाया है कि मॉड्यूल को खोजने के लिए इसे स्क्रिप्ट / config.js फ़ाइल को कोणीय में शामिल करना भी आवश्यक है, इस तरह: <script src = "script / config.js"> </ script>
Toni Gamez

75

एक ठंडा समाधान सभी पर्यावरण-विशिष्ट मूल्यों को कुछ अलग कोणीय मॉड्यूल में अलग कर सकता है, जो अन्य सभी मॉड्यूल पर निर्भर करते हैं:

angular.module('configuration', [])
       .constant('API_END_POINT','123456')
       .constant('HOST','localhost');

फिर आपके मॉड्यूल को उन प्रविष्टियों की आवश्यकता होती है जो इस पर निर्भरता की घोषणा कर सकते हैं:

angular.module('services',['configuration'])
       .factory('User',['$resource','API_END_POINT'],function($resource,API_END_POINT){
           return $resource(API_END_POINT + 'user');
       });

अब आप आगे के शांत सामान के बारे में सोच सकते हैं:

मॉड्यूल, जिसमें कॉन्फ़िगरेशन शामिल है उसे कॉन्फ़िगरेशन में विभाजित किया जा सकता है। जेएस, जो आपके पृष्ठ पर शामिल किया जाएगा।

यह स्क्रिप्ट आसानी से आप में से प्रत्येक द्वारा संपादित की जा सकती है, जब तक कि आप इस अलग फाइल को गिट में चेक नहीं करते हैं। लेकिन कॉन्फ़िगरेशन में जांच न करना आसान है यदि यह एक अलग फ़ाइल में है। इसके अलावा, आप इसे स्थानीय रूप से शाखा दे सकते हैं।

अब, यदि आपके पास ANT या Maven जैसा कोई बिल्ड-सिस्टम है, तो आपके आगे के चरण API_END_POINT मानों के लिए कुछ प्लेसहोल्डर्स को लागू कर सकते हैं, जो आपके विशिष्ट मूल्यों के साथ बिल्ड-टाइम के दौरान बदल दिए जाएंगे।

या आपके पास अपना है configuration_a.jsऔर configuration_b.jsबैकएंड पर फैसला करना है जिसमें शामिल होना है।


30

के लिए Gulp उपयोगकर्ताओं, घूंट एनजी-निरंतर भी साथ संयुक्त रूप से उपयोगी है घूंट-concat , घटना-स्ट्रीम और yargs

var concat = require('gulp-concat'),
    es = require('event-stream'),
    gulp = require('gulp'),
    ngConstant = require('gulp-ng-constant'),
    argv = require('yargs').argv;

var enviroment = argv.env || 'development';

gulp.task('config', function () {
  var config = gulp.src('config/' + enviroment + '.json')
    .pipe(ngConstant({name: 'app.config'}));
  var scripts = gulp.src('js/*');
  return es.merge(config, scripts)
    .pipe(concat('app.js'))
    .pipe(gulp.dest('app/dist'))
    .on('error', function() { });
});

मेरे कॉन्फ़िगरेशन फ़ोल्डर में मेरे पास ये फ़ाइलें हैं:

ls -l config
total 8
-rw-r--r--+ 1 .. ci.json
-rw-r--r--+ 1 .. development.json
-rw-r--r--+ 1 .. production.json

तब आप दौड़ सकते हैं gulp config --env developmentऔर वह कुछ इस तरह का निर्माण करेगा:

angular.module("app.config", [])
.constant("foo", "bar")
.constant("ngConstant", true);

मेरे पास यह युक्ति भी है:

beforeEach(module('app'));

it('loads the config', inject(function(config) {
  expect(config).toBeTruthy();
}));

क्या स्थूल एनजी के साथ निर्भरता सरणी को हटाने का एक तरीका है? मेरे पास मेरे स्थिरांक के लिए कोई निर्भरता नहीं है जैसे आपके पास इस तरह के "भोलेपन" में हैं। यदि मैं इसे शामिल नहीं करता हूं, तो मुझे एंगुलर.module ("my.module.config", []) के रूप में एक खाली निर्भरता सरणी मिलती है, लेकिन मुझे कोणीय.module ("my.module.config") के रूप में आउटपुट चाहिए। मुझे निरंतर एनजीआर में कोई विकल्प नहीं दिखता है, लेकिन मैं देख रहा हूं कि आप डिप्स पास कर सकते हैं: निरंतर पैकेज के ग्रन्ट एनजी में गलत। कोई मदद?
अरुण गोपालपुरी

17

इसे प्राप्त करने के लिए, मैं आपको AngularJS Environment Plugin का उपयोग करने का सुझाव देता हूं: https://www.npmjs.com/package/angular-environment

यहाँ एक उदाहरण है:

angular.module('yourApp', ['environment']).
config(function(envServiceProvider) {
    // set the domains and variables for each environment 
    envServiceProvider.config({
        domains: {
            development: ['localhost', 'dev.local'],
            production: ['acme.com', 'acme.net', 'acme.org']
            // anotherStage: ['domain1', 'domain2'], 
            // anotherStage: ['domain1', 'domain2'] 
        },
        vars: {
            development: {
                apiUrl: '//localhost/api',
                staticUrl: '//localhost/static'
                // antoherCustomVar: 'lorem', 
                // antoherCustomVar: 'ipsum' 
            },
            production: {
                apiUrl: '//api.acme.com/v2',
                staticUrl: '//static.acme.com'
                // antoherCustomVar: 'lorem', 
                // antoherCustomVar: 'ipsum' 
            }
            // anotherStage: { 
            //  customVar: 'lorem', 
            //  customVar: 'ipsum' 
            // } 
        }
    });

    // run the environment check, so the comprobation is made 
    // before controllers and services are built 
    envServiceProvider.check();
});

और फिर, आप अपने नियंत्रकों से चर को इस तरह से कॉल कर सकते हैं:

envService.read('apiUrl');

आशा करता हूँ की ये काम करेगा।


1
वह विकास और उत्पादन के बीच कैसे बदल जाता है?
मावग का कहना है कि मोनिका

हाय जुआन पाब्लो, या @Mawg अगर आपको यह पता चला। इससे पहले कि मैं एसओ पर एक प्रश्न पूछूं / गितुब पर एक मुद्दा उठा; angular-environmentपर्यावरण का पता कैसे लगाता है? यानी आपको अपने स्थानीय मशीन / वेब सर्वर पर क्या करने की आवश्यकता है ताकि यह पता चले कि यह क्रमशः देव / उत्पाद है?
स्टीवेईपी

डॉक्स को फिर से पढ़ना ... " envServiceProvider.check()... स्वचालित रूप से दिए गए डोमेन के आधार पर उपयुक्त वातावरण सेट करेगा"। इसलिए मुझे लगता है कि यह वर्तमान डोमेन का पता लगाता है और पर्यावरण को उचित रूप से सेट करता है - इसका परीक्षण करने का समय!
स्टीवीप

13

आप lvh.me:9000अपने AngularJS ऐप को एक्सेस करने के लिए उपयोग कर सकते हैं, ( lvh.meबस अंक 127.0.0.1 पर) और फिर एक अलग एंडपॉइंट निर्दिष्ट करें यदि lvh.meहोस्ट होस्ट करें:

app.service("Configuration", function() {
  if (window.location.host.match(/lvh\.me/)) {
    return this.API = 'http://localhost\\:7080/myapi/';
  } else {
    return this.API = 'http://localhost\\:8099/hisapi/';
  }
});

और फिर कॉन्फ़िगरेशन सेवा को इंजेक्ट करें और Configuration.APIजहां भी आपको एपीआई का उपयोग करने की आवश्यकता हो, उसका उपयोग करें:

$resource(Configuration.API + '/endpoint/:id', {
  id: '@id'
});

टैड क्लंकी, लेकिन मेरे लिए ठीक काम करता है, हालांकि कुछ अलग स्थिति में (एपीआई एंडपॉइंट्स उत्पादन और विकास में भिन्न होते हैं)।


1
इसलिए मुझे लगता है कि कई बार लोग चीजों को ओवरकम कर देते हैं। मेरे लिए साधारण उपयोग window.location.hostपर्याप्त से अधिक था।
जॉयसम

7

हम भी कुछ ऐसा कर सकते थे।

(function(){
    'use strict';

    angular.module('app').service('env', function env() {

        var _environments = {
            local: {
                host: 'localhost:3000',
                config: {
                    apiroot: 'http://localhost:3000'
                }
            },
            dev: {
                host: 'dev.com',
                config: {
                    apiroot: 'http://localhost:3000'
                }
            },
            test: {
                host: 'test.com',
                config: {
                    apiroot: 'http://localhost:3000'
                }
            },
            stage: {
                host: 'stage.com',
                config: {
                apiroot: 'staging'
                }
            },
            prod: {
                host: 'production.com',
                config: {
                    apiroot: 'production'
                }
            }
        },
        _environment;

        return {
            getEnvironment: function(){
                var host = window.location.host;
                if(_environment){
                    return _environment;
                }

                for(var environment in _environments){
                    if(typeof _environments[environment].host && _environments[environment].host == host){
                        _environment = environment;
                        return _environment;
                    }
                }

                return null;
            },
            get: function(property){
                return _environments[this.getEnvironment()].config[property];
            }
        }

    });

})();

और आप में controller/service, हम निर्भरता को इंजेक्ट कर सकते हैं और प्राप्त करने के लिए संपत्ति के साथ विधि प्राप्त कर सकते हैं।

(function() {
    'use strict';

    angular.module('app').service('apiService', apiService);

    apiService.$inject = ['configurations', '$q', '$http', 'env'];

    function apiService(config, $q, $http, env) {

        var service = {};
        /* **********APIs **************** */
        service.get = function() {
            return $http.get(env.get('apiroot') + '/api/yourservice');
        };

        return service;
    }

})();

$http.get(env.get('apiroot') मेजबान वातावरण के आधार पर url लौटाएगा।


5

अच्छा प्रश्न!

एक समाधान अपने config.xml फ़ाइल का उपयोग जारी रखने के लिए किया जा सकता है, और बैकएंड से अपने जेनरेट किए गए HTML को एपीआई एंडपॉइंट जानकारी प्रदान करें, जैसे कि (php में उदाहरण):

<script type="text/javascript">
angular.module('YourApp').constant('API_END_POINT', '<?php echo $apiEndPointFromBackend; ?>');
</script>

शायद एक सुंदर समाधान नहीं है, लेकिन यह काम करेगा।

एक अन्य समाधान API_END_POINTयह हो सकता है कि उत्पादन में जैसा होना चाहिए वैसा ही निरंतर मूल्य बनाए रखें , और अपनी मेजबानों-फ़ाइल को संशोधित करके केवल उस स्थान पर अपने स्थानीय एपीआई के लिए आग्रह करें।

या हो सकता है localStorageकि इस तरह से ओवरराइड्स का उपयोग करने वाला एक समाधान :

.factory('User',['$resource','API_END_POINT'],function($resource,API_END_POINT){
   var myApi = localStorage.get('myLocalApiOverride');
   return $resource((myApi || API_END_POINT) + 'user');
});

हाय joakimbeng, मैं समाधान है कि मैं php में उपयोग करने के लिए बात समझाने लिखा था। हम एक शुद्ध रैस्टफुल जावा बैकएंड के साथ एक शुद्ध जावास्क्रिप्ट क्लाइंट को कोड करने की कोशिश कर रहे हैं, इसलिए php / js मिक्स यह मेरा मामला नहीं है और यह भी जब मैं php में लिखता हूं तो मैं हमेशा php और js को मिश्रित नहीं रखने की कोशिश करता हूं। लेकिन उत्तर के लिए धन्यवाद। मुझे लगता है कि @kfis उत्तर समाधान काम कर सकता है: एक कॉन्फ़िगरेशन .js फ़ाइल एक कॉन्फ़िगरेशन मॉड्यूल वाले संस्करण नियंत्रण के तहत नहीं है। इस दृष्टिकोण के साथ, यदि यह आवश्यक हो, तो मैं परीक्षण उद्देश्य के लिए एक अलग कॉन्फ़िगरेशन मॉड्यूल इंजेक्ट / लोड कर सकता हूं। धन्यवाद दोस्तों।
रबीलानी

@ hal9087 मैं पूरी तरह से मिक्सिंग भाषाओं के हिस्से के बारे में सहमत हूं, इसे हर कीमत पर टाला जाना चाहिए :) मुझे कॉन्फ़िगरेशन पसंद है। जेएस समाधान भी, मैं इसे ध्यान में रखूंगा जब मुझे कुछ इसी तरह की आवश्यकता होगी!
जोकिंबेंग

4

थ्रेड को बहुत देर हो चुकी है, लेकिन एक तकनीक जो मैंने इस्तेमाल की है, प्री-एंगुलर, JSON और जेएस के लचीलेपन का लाभ लेने के लिए गतिशील रूप से संदर्भ संग्रह कुंजियों का उपयोग करना है, और पर्यावरण के निष्क्रिय तथ्यों (होस्ट सर्वर नाम, वर्तमान ब्राउज़र भाषा) का उपयोग करना है , आदि) के रूप में चुनिंदा भेदभाव करने के लिए इनपुट के रूप में / एक JSON डेटा संरचना के भीतर प्रत्यय प्रमुख नाम पसंद करते हैं।

यह न केवल तैनाती-पर्यावरण संदर्भ (प्रति ओपी) बल्कि किसी भी मनमाने संदर्भ (जैसे भाषा) को i18n या किसी भी अन्य विचरण को एक साथ प्रदान करने के लिए प्रदान करता है, और (आदर्श रूप से) एक एकल कॉन्फ़िगरेशन के भीतर, बिना दोहराव और आसानी से स्पष्ट।

10 लाइन्स वानीला जेएस के बारे में

ओवरली-सरलीकृत लेकिन क्लासिक उदाहरण: JSON-स्वरूपित गुण फ़ाइल में एक API एंडपॉइंट बेस URL जो प्रति वातावरण में भिन्न होता है जहां (natch) होस्ट सर्वर भी भिन्न होगा:

    ...
    'svcs': {
        'VER': '2.3',
        'API@localhost': 'http://localhost:9090/',
        'API@www.uat.productionwebsite.com': 'https://www.uat.productionwebsite.com:9090/res/',
        'API@www.productionwebsite.com': 'https://www.productionwebsite.com:9090/api/res/'
    },
    ...

भेदभाव फ़ंक्शन की एक कुंजी अनुरोध में सर्वर होस्टनाम है।

यह, स्वाभाविक रूप से, उपयोगकर्ता की भाषा सेटिंग्स के आधार पर एक अतिरिक्त कुंजी के साथ जोड़ा जा सकता है:

    ...
    'app': {
        'NAME': 'Ferry Reservations',
        'NAME@fr': 'Réservations de ferry',
        'NAME@de': 'Fähren Reservierungen'
    },
    ...

भेदभाव / वरीयता का दायरा व्यक्तिगत कुंजी तक सीमित हो सकता है (ऊपर) जहाँ "आधार" कुंजी को केवल तब ही अधिलेखित कर दिया जाता है यदि फ़ंक्शन के इनपुट के लिए एक मिलान कुंजी + प्रत्यय है - या संपूर्ण संरचना, और वह संरचना स्वयं पारस्परिक रूप से भेदभाव / वरीयता प्रत्यय के लिए पुनरावर्ती:

    'help': {
        'BLURB': 'This pre-production environment is not supported. Contact Development Team with questions.',
        'PHONE': '808-867-5309',
        'EMAIL': 'coder.jen@lostnumber.com'
    },
    'help@www.productionwebsite.com': {
        'BLURB': 'Please contact Customer Service Center',
        'BLURB@fr': 'S\'il vous plaît communiquer avec notre Centre de service à la clientèle',
        'BLURB@de': 'Bitte kontaktieren Sie unseren Kundendienst!!1!',
        'PHONE': '1-800-CUS-TOMR',
        'EMAIL': 'customer.service@productionwebsite.com'
    },

एसओ, अगर उत्पादन वेबसाइट पर जाने वाले उपयोगकर्ता के पास जर्मन ( डी ) भाषा वरीयता सेटिंग है, तो उपरोक्त कॉन्फ़िगरेशन नीचे गिर जाएगा:

    'help': {
        'BLURB': 'Bitte kontaktieren Sie unseren Kundendienst!!1!',
        'PHONE': '1-800-CUS-TOMR',
        'EMAIL': 'customer.service@productionwebsite.com'
    },

इस तरह की जादुई वरीयता / भेदभाव JSON- पुनर्लेखन समारोह कैसा दिखता है? बहुत ज्यादा नहीं:

// prefer(object,suffix|[suffixes]) by/par/durch storsoc
// prefer({ a: 'apple', a@env: 'banana', b: 'carrot' },'env') -> { a: 'banana', b: 'carrot' }
function prefer(o,sufs) {
    for (var key in o) {
        if (!o.hasOwnProperty(key)) continue; // skip non-instance props
        if(key.split('@')[1]) { // suffixed!
            // replace root prop with the suffixed prop if among prefs
            if(o[key] && sufs.indexOf(key.split('@')[1]) > -1) o[key.split('@')[0]] = JSON.parse(JSON.stringify(o[key]));

            // and nuke the suffixed prop to tidy up
            delete o[key];

            // continue with root key ...
            key = key.split('@')[0];
        }

        // ... in case it's a collection itself, recurse it!
        if(o[key] && typeof o[key] === 'object') prefer(o[key],sufs);

    };
};

हमारे कार्यान्वयन में, जिसमें कोणीय और पूर्व-कोणीय वेबसाइट शामिल हैं, हम केवल JSON को एक स्व-निष्पादित जेएस क्लोजर के भीतर रखकर अन्य संसाधन कॉल के आगे कॉन्फ़िगरेशन को अच्छी तरह से बूटस्ट्रैप करते हैं, जिसमें पसंदीदा () फ़ंक्शन और होस्टनाम के बुनियादी गुण शामिल हैं भाषा-कोड (और आपके द्वारा आवश्यक किसी भी अतिरिक्त मनमाने प्रत्यय को स्वीकार कर सकता है):

(function(prefs){ var props = {
    'svcs': {
        'VER': '2.3',
        'API@localhost': 'http://localhost:9090/',
        'API@www.uat.productionwebsite.com': 'https://www.uat.productionwebsite.com:9090/res/',
        'API@www.productionwebsite.com': 'https://www.productionwebsite.com:9090/api/res/'
    },
    ...
    /* yadda yadda moar JSON und bisque */

    function prefer(o,sufs) {
        // body of prefer function, broken for e.g.
    };

    // convert string and comma-separated-string to array .. and process it
    prefs = [].concat( ( prefs.split ? prefs.split(',') : prefs ) || []);
    prefer(props,prefs);
    window.app_props = JSON.parse(JSON.stringify(props));
})([location.hostname, ((window.navigator.userLanguage || window.navigator.language).split('-')[0])  ] );

एक पूर्व-कोणीय साइट अब संदर्भित करने के लिए एक ढह गई (कोई @ प्रत्यय कुंजियाँ) window.app_props होगी।

एक कोणीय साइट, बूटस्ट्रैप / इनिट स्टेप के रूप में, बस डेड-ड्रॉप प्रॉप ऑब्जेक्ट को $ rootScope में कॉपी करता है, और (वैकल्पिक रूप से) इसे ग्लोबल / विंडो स्कोप से नष्ट कर देता है

app.constant('props',angular.copy(window.app_props || {})).run( function ($rootScope,props) { $rootScope.props = props; delete window.app_props;} );

बाद में नियंत्रकों में इंजेक्ट किया जाना है:

app.controller('CtrlApp',function($log,props){ ... } );

या विचारों में बाइंडिंग से संदर्भित:

<span>{{ props.help.blurb }} {{ props.help.email }}</span>

चेतावनियां? @ वर्ण जेएस / जेएसएन चर / कुंजी नामकरण मान्य नहीं है, लेकिन अब तक स्वीकृत है। यदि यह एक डील-ब्रेकर है, तो किसी भी कन्वेंशन का विकल्प चुनें, जैसे कि "__" (डबल अंडरस्कोर) जब तक आप उससे चिपके रहते हैं।

तकनीक को सर्वर-साइड पर लागू किया जा सकता है, जिसे जावा या सी # में पोर्ट किया जा सकता है, लेकिन आपकी दक्षता / कॉम्पैक्टनेस भिन्न हो सकती है।

वैकल्पिक रूप से, फ़ंक्शन / कन्वेंशन आपके फ्रंट-एंड कम्पाइल स्क्रिप्ट का हिस्सा हो सकता है, जिससे कि पूरा गोर ऑल-इनवायरमेंट / ऑल-लैंग्वेज JSON कभी भी वायर पर प्रसारित न हो।

अपडेट करें

हमने इस तकनीक का उपयोग एक कुंजी को कई प्रत्ययों की अनुमति देने के लिए किया है, ताकि संग्रह का उपयोग करने के लिए मजबूर होने से बचने के लिए (आप अभी भी, जितनी गहराई से चाहें), और साथ ही पसंदीदा प्रत्ययों के आदेश का सम्मान कर सकें।

उदाहरण (कार्यशील jsFiddle को भी देखें ):

var o = { 'a':'apple', 'a@dev':'apple-dev', 'a@fr':'pomme',
          'b':'banana', 'b@fr':'banane', 'b@dev&fr':'banane-dev',
          'c':{ 'o':'c-dot-oh', 'o@fr':'c-point-oh' }, 'c@dev': { 'o':'c-dot-oh-dev', 'o@fr':'c-point-oh-dev' } };

/*1*/ prefer(o,'dev');        // { a:'apple-dev', b:'banana',     c:{o:'c-dot-oh-dev'}   }
/*2*/ prefer(o,'fr');         // { a:'pomme',     b:'banane',     c:{o:'c-point-oh'}     }
/*3*/ prefer(o,'dev,fr');     // { a:'apple-dev', b:'banane-dev', c:{o:'c-point-oh-dev'} }
/*4*/ prefer(o,['fr','dev']); // { a:'pomme',     b:'banane-dev', c:{o:'c-point-oh-dev'} }
/*5*/ prefer(o);              // { a:'apple',     b:'banana',     c:{o:'c-dot-oh'}       }

1/2 (मूल उपयोग) '@dev' कुंजी पसंद करता है, अन्य सभी प्रत्यय कुंजियों को छोड़ देता है

3 '@ देवा' के ऊपर '@देव' पसंद करते हैं, अन्य सभी के ऊपर '@ देव और फ्र' पसंद करते हैं

4 (3 के समान) लेकिन '@ देवा' पर '@fr' पसंद करता है)

5 कोई पसंदीदा प्रत्यय नहीं, सभी प्रत्यय गुणों को गिराता है

यह प्रत्येक प्रत्यय संपत्ति को स्कोर करके और गैर-प्रत्यय संपत्ति के लिए एक प्रत्यय संपत्ति के मूल्य को बढ़ावा देने के द्वारा पूरा करता है जब संपत्तियों पर पुनरावृत्ति करता है और एक उच्च स्कोर वाले प्रत्यय पाता है।

इस संस्करण में कुछ क्षमताएँ, जिनमें JSON पर निर्भरता को गहरी-प्रतिलिपि करने के लिए, और केवल उन वस्तुओं में पुनरावृत्ति करना शामिल है जो उनकी गहराई पर स्कोरिंग दौर से बचते हैं:

function prefer(obj,suf) {
    function pr(o,s) {
        for (var p in o) {
            if (!o.hasOwnProperty(p) || !p.split('@')[1] || p.split('@@')[1] ) continue; // ignore: proto-prop OR not-suffixed OR temp prop score
            var b = p.split('@')[0]; // base prop name
            if(!!!o['@@'+b]) o['@@'+b] = 0; // +score placeholder
            var ps = p.split('@')[1].split('&'); // array of property suffixes
            var sc = 0; var v = 0; // reset (running)score and value
            while(ps.length) {
                // suffix value: index(of found suffix in prefs)^10
                v = Math.floor(Math.pow(10,s.indexOf(ps.pop())));
                if(!v) { sc = 0; break; } // found suf NOT in prefs, zero score (delete later)
                sc += v;
            }
            if(sc > o['@@'+b]) { o['@@'+b] = sc; o[b] = o[p]; } // hi-score! promote to base prop
            delete o[p];
        }
        for (var p in o) if(p.split('@@')[1]) delete o[p]; // remove scores
        for (var p in o) if(typeof o[p] === 'object') pr(o[p],s); // recurse surviving objs
    }
    if( typeof obj !== 'object' ) return; // validate
    suf = ( (suf || suf === 0 ) && ( suf.length || suf === parseFloat(suf) ) ? suf.toString().split(',') : []); // array|string|number|comma-separated-string -> array-of-strings
    pr(obj,suf.reverse());
}


-8

क्या आपने इस प्रश्न और इसके उत्तर को देखा है?

आप इस तरह से आप के लिए एक विश्व स्तर पर मान्य मूल्य निर्धारित कर सकते हैं:

app.value('key', 'value');

और फिर इसे अपनी सेवाओं में उपयोग करें। आप इस कोड को config.js फ़ाइल में ले जा सकते हैं और इसे पृष्ठ लोड या किसी अन्य सुविधाजनक क्षण पर निष्पादित कर सकते हैं।


7
क्या कोई समझा सकता है कि यह इतना बुरा जवाब क्यों है? इसे बड़े पैमाने पर डाउनवोट किया गया है, लेकिन एक भी टिप्पणी नहीं ...
जूल

5
यह नरक के रूप में पुराना है, लेकिन अगर मुझे यह अनुमान लगाना था कि डाउनवोट क्यों है, तो यह इसलिए है क्योंकि यह पर्यावरण विशिष्ट कॉन्फ़िगरेशन की समस्या को संबोधित नहीं करता है, यह किसी भी पुराने ऐप में वैश्विक मूल्य निर्धारित करने के लिए .value () का उपयोग करने के लिए सिर्फ एक सुझाव है। मूल प्रश्न मापदंडों के साथ env या किसी भी चीज के आधार पर कोई इसका उपयोग कैसे करेगा, इसका कोई उल्लेख नहीं है।
coblr
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.