Làm cách nào để định cấu hình các môi trường khác nhau trong Angular.js?


220

Làm thế nào để bạn quản lý các biến / hằng cấu hình cho các môi trường khác nhau?

Đây có thể là một ví dụ:

API còn lại của tôi có thể truy cập được localhost:7080/myapi/, nhưng người bạn của tôi hoạt động trên cùng một mã trong kiểm soát phiên bản Git đã triển khai API trên Tomcat của anh ấy localhost:8099/hisapi/.

Giả sử rằng chúng ta có một cái gì đó như thế này:

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

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

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

Làm cách nào để tôi tự động tiêm giá trị chính xác của điểm cuối API, tùy thuộc vào môi trường?

Trong PHP tôi thường làm loại công cụ này với một config.username.xmltệp, hợp nhất tệp cấu hình cơ bản (config.xml) với tệp cấu hình môi trường cục bộ được nhận dạng theo tên của người dùng. Nhưng tôi không biết cách quản lý loại điều này trong JavaScript?

Câu trả lời:


209

Tôi hơi muộn với chủ đề này, nhưng nếu bạn đang sử dụng Grunt thì tôi đã thành công lớn grunt-ng-constant.

Phần cấu hình cho ngconstanttôi Gruntfile.jstrông giống như

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

Các tác vụ sử dụng ngconstanttrông giống như

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

Vì vậy, chạy grunt serversẽ tạo ra một config.jstập tin app/scripts/trông giống như

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

Cuối cùng, tôi tuyên bố sự phụ thuộc vào bất kỳ mô-đun nào cần nó:

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

Bây giờ hằng số của tôi có thể được tiêm phụ thuộc khi cần thiết. Ví dụ,

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

10
Thay vì đặt 'ngconstant:development'trong 'serve'- nếu bạn đặt nó trong cấu hình đồng hồ dưới 'gruntfile'như tasks: ['ngconstant:development']- bạn sẽ không cần phải khởi động lại grunt servekhi bạn cập nhật các biến phát triển trong gruntfile.
dành

10
Thay vì thêm các hằng số của bạn vào gruntfile.js, bạn có thể đặt các tệp riêng biệt như sau:package: grunt.file.readJSON('development.json')
Guilhem Soulas

3
Có một cú pháp cập nhật cho Gruntfile.js trong phiên bản 0,5 của grunt-ng-hằng: github.com/werk85/grunt-ng-constant/issues/31 . Câu trả lời tuyệt vời, cảm ơn!
pherris

10
Đối với những người sử dụng gulp, có gulp-ng-hằng .
Dheeraj Vepakomma

4
Tôi đã tìm thấy Cũng cần phải đưa tệp scripts / config.js vào góc để tìm mô-đun, như thế này: <script src = "scripts / config.js"> </ script>
Toni Gamez

75

Một giải pháp tuyệt vời có thể là tách tất cả các giá trị cụ thể của môi trường thành một số mô-đun góc riêng biệt, mà tất cả các mô-đun khác phụ thuộc vào:

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

Sau đó, các mô-đun của bạn cần các mục đó có thể khai báo một phụ thuộc vào nó:

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

Bây giờ bạn có thể nghĩ về những thứ tuyệt vời hơn nữa:

Mô-đun chứa cấu hình có thể được tách thành configure.js, sẽ được đưa vào trang của bạn.

Tập lệnh này có thể dễ dàng được chỉnh sửa bởi mỗi bạn, miễn là bạn không kiểm tra tệp riêng biệt này thành git. Nhưng sẽ dễ dàng hơn nếu không kiểm tra cấu hình nếu nó nằm trong một tệp riêng biệt. Ngoài ra, bạn có thể phân nhánh nó tại địa phương.

Bây giờ, nếu bạn có một hệ thống xây dựng, như ANT hoặc Maven, các bước tiếp theo của bạn có thể là triển khai một số trình giữ chỗ cho các giá trị API_END_POINT, sẽ được thay thế trong thời gian xây dựng, với các giá trị cụ thể của bạn.

Hoặc bạn có configuration_a.jsconfiguration_b.jsvà quyết định tại phụ trợ bao gồm.


30

Đối với người dùng Gulp , gulp-ng-hằng cũng hữu ích khi kết hợp với gulp-concat , event-streamyargs .

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

Trong thư mục cấu hình của tôi, tôi có các tệp này:

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

Sau đó, bạn có thể chạy gulp config --env developmentvà điều đó sẽ tạo ra một cái gì đó như thế này:

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

Tôi cũng có thông số này:

beforeEach(module('app'));

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

Có cách nào để loại bỏ mảng phụ thuộc với hằng số gulp ng không? Tôi không có bất kỳ sự phụ thuộc nào vào các hằng số của tôi như bạn có trong ví dụ này "ngAnimate". Nếu tôi không bao gồm nó, tôi nhận được một mảng phụ thuộc trống là angular.module ("my.module.config", []) nhưng tôi muốn đầu ra là angular.module ("my.module.config"). Tôi không thấy bất kỳ tùy chọn nào trong hằng số gulp ng nhưng tôi thấy rằng bạn có thể vượt qua deps: false trong gói hằng số grunt ng. Có ai giúp đỡ không?
Arun Gopalpuri

17

Để đạt được điều đó, tôi khuyên bạn nên sử dụng Plugin AngularJS Môi trường: https://www.npmjs.com/package/angular-en môi trường

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

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

Và sau đó, bạn có thể gọi các biến từ bộ điều khiển của mình như sau:

envService.read('apiUrl');

Hy vọng nó giúp.


1
Làm thế nào để anh ấy chuyển đổi giữa phát triển và sản xuất?
Mawg nói rằng phục hồi Monica

Xin chào Juan Pablo hoặc @Mawg nếu bạn tìm ra nó. Trước khi tôi đặt câu hỏi về SO / nêu vấn đề trên Github; Làm thế nào để angular-environmentphát hiện môi trường? tức là bạn cần làm gì trên máy chủ / máy chủ web cục bộ để nó biết rằng đó là dev / prod tương ứng?
StevieP

Đọc lại các tài liệu ... " envServiceProvider.check()... sẽ tự động thiết lập môi trường phù hợp dựa trên các miền đã cho". Vì vậy, tôi nghĩ rằng nó phát hiện tên miền hiện tại và thiết lập môi trường phù hợp - thời gian để kiểm tra nó!
StevieP

13

Bạn có thể sử dụng lvh.me:9000để truy cập ứng dụng AngularJS của mình, ( lvh.mechỉ vào 127.0.0.1) và sau đó chỉ định một điểm cuối khác nếu lvh.melà máy chủ:

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

Và sau đó tiêm dịch vụ Cấu hình và sử dụng Configuration.APIbất cứ nơi nào bạn cần để truy cập API:

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

Một chút lộn xộn, nhưng hoạt động tốt đối với tôi, mặc dù trong một tình huống hơi khác nhau (các điểm cuối API khác nhau trong sản xuất và phát triển).


1
Vì vậy, tôi nghĩ rằng nhiều khi mọi người quá phức tạp. Việc sử dụng đơn giản window.location.hostlà quá đủ cho tôi.
joseym

7

Chúng tôi cũng có thể làm một cái gì đó như thế này.

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

    });

})();

Và trong của bạn controller/service, chúng ta có thể tiêm phụ thuộc và gọi phương thức get với thuộc tính được truy cập.

(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') sẽ trả về url dựa trên môi trường máy chủ.


5

Câu hỏi hay!

Một giải pháp có thể là tiếp tục sử dụng tệp config.xml của bạn và cung cấp thông tin điểm cuối api từ phụ trợ cho html được tạo của bạn, như thế này (ví dụ trong php):

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

Có thể không phải là một giải pháp đẹp, nhưng nó sẽ làm việc.

Một giải pháp khác có thể là giữ API_END_POINTgiá trị không đổi như trong sản xuất và chỉ sửa đổi tệp máy chủ của bạn để trỏ url đó đến api cục bộ của bạn.

Hoặc có thể là một giải pháp sử dụng localStorageđể ghi đè, như thế này:

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

Xin chào joakimbeng, tôi đã viết giải pháp mà tôi sử dụng trong php để giải thích vấn đề. Chúng tôi đang cố gắng mã hóa một máy khách javascript thuần túy với một phụ trợ java RESTful thuần túy, vì vậy, php / js không phải là trường hợp của tôi và cả khi tôi viết bằng php, tôi luôn cố gắng giữ php và js không bị trộn lẫn. nhưng cảm ơn vì câu trả lời Tôi nghĩ rằng giải pháp trả lời @kfis có thể hoạt động: tệp configure.js không thuộc kiểm soát phiên bản có chứa mô-đun cấu hình. Với phương pháp này, tôi có thể tiêm / tải một mô-đun cấu hình khác cho mục đích thử nghiệm, nếu cần thiết. Cảm ơn các bạn.
rbarilani

@ hal9087 Tôi hoàn toàn đồng ý về phần ngôn ngữ trộn, nên tránh bằng mọi giá :) Tôi cũng thích giải pháp configure.js, tôi sẽ ghi nhớ khi tôi cần thứ gì đó tương tự!
joakimbeng

4

Rất muộn với chủ đề, nhưng một kỹ thuật tôi đã sử dụng, trước Angular, là tận dụng JSON và tính linh hoạt của JS để tham chiếu động các khóa bộ sưu tập và sử dụng các sự kiện không thể thay đổi của môi trường (tên máy chủ lưu trữ, ngôn ngữ trình duyệt hiện tại , v.v.) làm đầu vào để phân biệt chọn lọc / thích các tên khóa có hậu tố trong cấu trúc dữ liệu JSON.

Điều này không chỉ cung cấp bối cảnh môi trường triển khai (trên mỗi OP) mà bất kỳ bối cảnh tùy ý nào (như ngôn ngữ) để cung cấp i18n hoặc bất kỳ phương sai nào khác được yêu cầu đồng thời, và (lý tưởng) trong một bảng kê khai cấu hình duy nhất, không trùng lặp và rõ ràng.

GIỚI THIỆU VỀ 10 DÒNG VANILLA JS

Ví dụ quá đơn giản nhưng cổ điển: URL cơ sở điểm cuối API trong tệp thuộc tính được định dạng JSON thay đổi theo từng môi trường trong đó (natch) máy chủ lưu trữ cũng sẽ thay đổi:

    ...
    '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/'
    },
    ...

Chìa khóa cho chức năng phân biệt đối xử chỉ đơn giản là tên máy chủ trong yêu cầu.

Điều này, một cách tự nhiên, có thể được kết hợp với một khóa bổ sung dựa trên cài đặt ngôn ngữ của người dùng:

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

Phạm vi của phân biệt đối xử / ưu tiên có thể được giới hạn trong các khóa riêng lẻ (như trên) trong đó khóa "cơ sở" chỉ được ghi đè nếu có khóa khớp + hậu tố cho các đầu vào của hàm - hoặc toàn bộ cấu trúc và chính cấu trúc đó phân tích đệ quy để phù hợp với hậu tố phân biệt đối xử / ưu tiên:

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

Vì vậy, nếu người dùng truy cập vào trang web sản xuất có Đức ( de ) thiết lập tuỳ chọn ngôn ngữ, cấu hình trên sẽ sụp đổ đến:

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

Hàm viết lại JSON ưa thích / phân biệt đối xử như vậy trông như thế nào? Không nhiều:

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

    };
};

Trong các triển khai của chúng tôi, bao gồm các trang web Angular và pre-Angular, chúng tôi chỉ cần khởi động lại cấu hình trước các lệnh gọi tài nguyên khác bằng cách đặt JSON trong một bao đóng JS tự thực thi, bao gồm hàm prefer () và cung cấp các thuộc tính cơ bản của tên máy chủ và mã ngôn ngữ (và chấp nhận bất kỳ hậu tố tùy ý bổ sung nào bạn có thể cần):

(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])  ] );

Một trang web trước Angular bây giờ sẽ có một cửa sổ được thu gọn (không có hậu tố @) .app_props để tham khảo.

Một trang web Angular, như một bước bootstrap / init, chỉ cần sao chép đối tượng đạo cụ đã chết vào $ rootScope và (tùy chọn) phá hủy nó từ phạm vi toàn cầu / cửa sổ

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

để sau đó được tiêm vào bộ điều khiển:

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

hoặc được đề cập từ các ràng buộc trong quan điểm:

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

Hãy cẩn thận? Ký tự @ không phải là cách đặt tên biến / khóa JS / JSON hợp lệ, nhưng cho đến nay vẫn được chấp nhận. Nếu đó là một công cụ thỏa thuận, hãy thay thế cho bất kỳ quy ước nào bạn thích, chẳng hạn như "__" (gạch dưới gấp đôi) miễn là bạn tuân thủ.

Kỹ thuật này có thể được áp dụng phía máy chủ, được chuyển sang Java hoặc C # nhưng hiệu quả / độ gọn của bạn có thể thay đổi.

Cách khác, hàm / quy ước có thể là một phần của tập lệnh biên dịch mặt trước của bạn, do đó, JSON toàn môi trường / tất cả ngôn ngữ hoàn toàn không bao giờ được truyền qua dây.

CẬP NHẬT

Chúng tôi đã phát triển việc sử dụng kỹ thuật này để cho phép nhiều hậu tố vào một khóa, để tránh bị buộc phải sử dụng các bộ sưu tập (bạn vẫn có thể, sâu như bạn muốn), và cũng để tôn vinh thứ tự của các hậu tố ưa thích.

Ví dụ (cũng xem jsFiddle hoạt động ):

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 (sử dụng cơ bản) thích các phím '@dev', loại bỏ tất cả các khóa có hậu tố khác

3 thích '@dev' hơn '@fr', thích '@ dev & fr' hơn tất cả những người khác

4 (giống như 3 nhưng thích '@fr' hơn '@dev')

5 không có hậu tố ưa thích, giảm TẤT CẢ các thuộc tính hậu tố

Nó thực hiện điều này bằng cách cho điểm từng thuộc tính có hậu tố và phát huy giá trị của thuộc tính có hậu tố thành thuộc tính không có hậu tố khi lặp qua các thuộc tính và tìm hậu tố có điểm cao hơn.

Một số tính hiệu quả trong phiên bản này, bao gồm loại bỏ sự phụ thuộc vào JSON vào bản sao sâu và chỉ đệ quy vào các đối tượng tồn tại trong vòng ghi điểm ở độ sâu của chúng:

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

Bạn đã thấy câu hỏi này và câu trả lời của nó?

Bạn có thể đặt giá trị hợp lệ toàn cầu cho ứng dụng của mình như thế này:

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

và sau đó sử dụng nó trong các dịch vụ của bạn. Bạn có thể di chuyển mã này sang tệp config.js và thực thi mã khi tải trang hoặc thời điểm thuận tiện khác.


7
Ai đó có thể vui lòng giải thích tại sao đây là một câu trả lời tồi? Nó đã bị hạ cấp ồ ạt, nhưng không phải là một bình luận ...
gửi vào

5
Điều này đã cũ như địa ngục, nhưng nếu tôi phải đoán tại sao các downvote, thì đó là vì nó không giải quyết được vấn đề về cấu hình cụ thể của môi trường, đó chỉ là một gợi ý sử dụng .value () để đặt giá trị toàn cầu trong bất kỳ ứng dụng cũ nào. Không có đề cập về cách người ta sẽ sử dụng điều này tùy thuộc vào env hoặc bất cứ điều gì dọc theo các tham số câu hỏi ban đầu.
coblr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.