2014-10-23 4 views
0

У меня есть следующие службы angularJSJavascript частные функции и Object.prototype продлить

define(["angular"], function(Angular) { 

var dataStorageService = function() { 
    var serviceConstructor = function() { 
     var _getColor = function(color) { 
      return this.config.categoryColorMapping.colors[color]; 
     } 
    } 

    var serviceInstance = new serviceConstructor(); 

    angular.extend(serviceInstance.prototype, { 
     config: { 
      numberOfMessagesDisplayed: 5, 
      maxTitleLength: 48, 
      maxPreambleLength: 140, 
      categoryColorMapping: { 
       colors : { 
        nyheter: '#2B2B2B', 
        sport: '#F59331', 
        underholding: '#F9B00D' 
       }, 
       categories: { 
        nyheter: _getColor('nyheter'), 
        sport: _getColor('sport'), 
        underholding: _getColor('underholding') 
       } 
      } 
     }, 
     get: function(param) { 
      if(this.config.hasOwnProperty(param)) { 
       return this.config[param]; 
      } else { 
       console.warn('Playlist::configService:no "' + param + '" config found'); 
       return false; 
      } 
     }, 
     set: function(param, value) { 
      this.config[param] = value; 
     } 
    }); 

    return serviceInstance; 
}; 

return dataStorageService; 
}); 

теперь моя цель состоит в том, чтобы сделать общественные следующие методы:

  1. получить
  2. набор

и я хочу использовать метод _getColor, но я хочу использовать его в конфигурации объекта JSON. Когда я запускаю код у меня есть

«ReferenceError: _getColor не определен»

является его possibie к achievie это так? (чтобы иметь _getColor private и использовать его в объекте JSON в angular.extend?)

ответ

1

функции может быть разделен и по-прежнему быть частными, экземпляр конкретных частные члены должны быть определены в конструкторе, хотя. Так как ваша частная функция не требуется доступ к экземпляра конкретных частных пользователей вы можете сделать следующее:

define(["angular"], function(Angular) { 

var dataStorageService = function() { 
    var serviceConstructor = function() { 
    } 

    var serviceInstance = new serviceConstructor(); 
    //IIFE returning object that will have private members as closure 
    // privileged methods have to be in the same function body as the 
    // private fucnction 
    serviceInstance.prototype = (function() { 
     var _getColor = function(instance, color) { 
      return instance.config.categoryColorMapping.colors[color]; 
     }; 
     return { 
      constructor: serviceConstructor 
      ,config: { 
      numberOfMessagesDisplayed: 5, 
      maxTitleLength: 48, 
      maxPreambleLength: 140, 
      categoryColorMapping: { 
       colors : { 
        nyheter: '#2B2B2B', 
        sport: '#F59331', 
        underholding: '#F9B00D' 
       }, 
       categories: { 
        //since categories is a sub object of serviceinstance.categorycolormapper 
        // it is not possible to get the instance of serviceinstance 
        // at this time unless you set it in the constructor 
        // solution could be that each serviceinstance has it's own categorycolormaper 
        // and when categorycolormapper is created pass the serviceinstance instance 
        nyheter: _getColor(this,'nyheter'), 
        sport: _getColor(this, 'sport'), 
        underholding: _getColor(this, 'underholding') 
       } 
      } 
      }, 
      get: function(param) { 
      if(this.config.hasOwnProperty(param)) { 
       return this.config[param]; 
      } else { 
       console.warn('Playlist::configService:no "' + param + '" config found'); 
       return false; 
      } 
      }, 
      set: function(param, value) { 
      this.config[param] = value; 
      } 
     } 
    }()); 

    return serviceInstance; 
}; 

return dataStorageService; 
}); 

Более подробную информацию о конструкторах функций и прототипа можно найти здесь: https://stackoverflow.com/a/16063711/1641941

1

Функции, добавленные в prototype, определены вне лексической области конструктора и, следовательно, не имеют доступа к «частным» методам.

Первые разделяются между всеми экземплярами, а последние являются экземплярами. Единственный способ обойти это - явно экспортировать функцию (для каждого экземпляра) как свойство экземпляра, что делает ее не частной.

+0

Частные методы могут быть добавлены, когда вы установите прототип для возвращаемого значения на IIFE. Метод не является специфичным для экземпляра, поэтому это возможно. Отдельные члены экземпляра должны быть определены в функции конструктора, а также все привилегированные методы, которым необходимо получить к ним доступ. Существуют другие шаблоны для имитации таких защищенных объектов, как этот: http://stackoverflow.com/a/21800194/1641941 – HMR

0

В определении serviceConstructor оных следующей строки после определения _getColor

serviceConstructor.prototype._getColor = _getColor ; 
+0

да, но тогда это будет общедоступно –

+0

, и каждый раз, когда вы создаете новый экземпляр, экземпляр _every_ будет использовать ссылка на _that конкретную версию экземпляра функции, и эта функция будет иметь доступ только к _that instance's_ другим частным переменным и методам. – Alnitak

+0

Область действия _getColor полностью заблокирована внутри конструктора. используйте любую ссылочную переменную, объявленную в dataStorageService в качестве канала, чтобы получить доступность _getColor. // dataStorageService ... var internal = {}; // ... внутри конструктора internal._getColor = _getColor; – Dinesh

Смежные вопросы