Как мне динамически изменять значение переменной внутри службы Angularjs из контроллера?

Мне нужно иметь возможность изменять значение переменной внутри службы Angularjs с контроллера в том же модуле. Версия TL; DR ниже ...

У меня есть встроенная система с RESTful API, описываемая файлом swagger. Я получаю к нему доступ через приложение Angularjs. Чтобы создать это приложение, я использовал swagger-codegen для автоматического создания сервисов. Это приводит к тому, что службе передается базовый путь, который используется внутри службы от вызова к $ http. Сервис выглядит так:

API.Client.MyApi = function($http, $httpParamSerializer, $injector) {
  /** @private {!string} */
  this.basePath_ = $injector.has('MyApiBasePath') ?
               /** @type {!string} */ ($injector.get('MyApiBasePath')) :
               'http://localhost/';

  ...

}

В моем файле angular app.js у меня есть следующее:

var myApp = angular.module('MyApp', [
])
  .service('MyApi', API.Client.MyApi)
  .value('MyApiBasePath', 'http://192.168.1.128');

Все это хорошо работает. Однако я хочу иметь возможность устанавливать базовый путь (в частности, IP-адрес) устройства из приложения. Но служба запускается с самого начала, и я не знаю, как заставить контроллер обновлять служебную переменную basePath_.

Я мог бы переписать сервисные функции, чтобы они принимали базовый путь в качестве параметра, но я не хочу переписывать сервисы, которые они автоматически генерируют с помощью swagger-codegen.

Я открыт для любого решения - ищу совета, как лучше всего это сделать.

ОБНОВЛЕНИЕ: 24.05.2016 - кто-то попросил меня опубликовать код чванства. Вот соответствующая часть одного из файлов, включая начальную служебную функцию, а также метод ...

API.Client.MyApi = function($http, $httpParamSerializer, $injector) {
  /** @private {!string} */
  this.basePath_ = $injector.has('MyApiBasePath') ?
                   /** @type {!string} */ ($injector.get('MyApiBasePath')) :
                   'http://localhost/';

  /** @private {!Object<string, string>} */
  this.defaultHeaders_ = $injector.has('MyApiDefaultHeaders') ?
                   /** @type {!Object<string, string>} */ (
                       $injector.get('MyApiDefaultHeaders')) :
                   {};

  /** @private {!angular.$http} */
  this.http_ = $http;

  /** @private {!Object} */
  this.httpParamSerializer_ = $injector.get('$httpParamSerializer');
}
API.Client.MyApi.$inject = ['$http', '$httpParamSerializer', '$injector'];

/**
 * Thingy Outputs
 * Returns the state of all thingys
 * @param {!angular.$http.Config=} opt_extraHttpRequestParams Extra HTTP parameters to send.
 * @return {!angular.$q.Promise<!Array<!API.Client.boolGetModel>>}
 */
API.Client.MyApi.prototype.thingyGet = function(opt_extraHttpRequestParams) {
  /** @const {string} */
  var path = this.basePath_ + '/thingys';

  /** @type {!Object} */
  var queryParameters = {};

  /** @type {!Object} */
  var headerParams = angular.extend({}, this.defaultHeaders);
  /** @type {!Object} */
  var httpRequestParams = {
    method: 'GET',
    url: path,
    json: true,


    params: queryParameters,
    headers: headerParams
  };

  if (opt_extraHttpRequestParams) {
    httpRequestParams = angular.extend(httpRequestParams, opt_extraHttpRequestParams);
  }

  return this.http_(httpRequestParams);
}

person user5890478    schedule 15.05.2016    source источник


Ответы (1)


Вам не нужно редактировать сгенерированную фабрику. Вы можете назначить URL-адрес базового пути непосредственно из контроллера экземпляру фабрики, созданной с помощью swagger-codegen.

Конструктор, который генерирует swagger-codegen, выглядит следующим образом:

function MyService(options, cache) {
            var domain = (typeof options === 'object') ? options.domain : options;
            this.domain = typeof(domain) === 'string' ? domain : 'http://localhost:8000';
            if (this.domain.length === 0) {
                throw new Error('Domain parameter must be specified as a string.');
            }
            cache = cache || ((typeof options === 'object') ? options.cache : cache);
            this.cache = cache;
        }

Затем в вашем контроллере вам нужно только создать экземпляр объекта с URL-адресом в параметре конструктора:

var myServiceObj = new MyService("http://www.pizza.it/api");
person Matteo Brighi    schedule 22.05.2016
comment
Предписанный метод (на примерах чванства), который я описал выше (с .service / .value как часть объявления модуля angular. Когда я пытаюсь сделать то, что вы рекомендуете - var myserviceobj = new API.Client.MyApi, я получаю: API. Client.MyApi не является конструктором. - person user5890478; 24.05.2016
comment
Не могли бы вы выложить сюда все файлы, сгенерированные swagger-codegen, пожалуйста? - person Matteo Brighi; 24.05.2016
comment
Я отредактировал приведенный выше код, чтобы показать файл swagger-codegen. - person user5890478; 25.05.2016