2016-12-12 6 views
1

Я написал Угловую фабрику для хранения объекта, который мне нужно передать в разные контроллеры. Завод выглядит следующим образом:двусторонняя привязка в угловых фабриках

app.factory('SearchEngineConfigs', function() { 
    var configs = { 
     isInternational: false, 
     TripType: 1, 
     journeys: [] 
    } 
    var _setInternational = function(val) { 
     configs.isInternational = val; 
    } 
    var _setTripType = function(val) { 
     configs.TripType = val; 
    } 
    var _setJourneys = function(journeys) { 
     configs.journeys = journeys; 
    } 

    var _getConfigs = function() { 
     return configs; 
    } 
    return { 
     setInternatioanl: _setInternational, 
     setTripType: _setTripType, 
     setJourneys: _setJourneys, 
     getConfigs: _getConfigs 
    } 
}); 

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

SearchEngineConfigs.setInternatioanl($scope.searchEngine.isInternational); 
SearchEngineConfigs.setTripType($scope.searchEngine.TripType);    
SearchEngineConfigs.setJourneys($scope.journeys.slice()); 

Пока все хорошо. Что происходит сейчас, так это то, что каждый раз, когда я меняю, скажем, $scope.searchEngine.isInternational, не вызывая фабричный метод SearchEngineConfigs.setInternatioanl, это изменение все еще отражается на фабрике и, таким образом, обновляет это свойство в другом контроллере, который использует этот завод одновременно с первым контроллером. Как я могу избежать этого? Я хочу изменить значение объекта внутри фабрики, когда я объясняю, что вызываю соответствующий метод фабрики.

ответ

1

Вы можете использовать angular.copy, чтобы избежать позволяя любые ссылки на свои внутренние состояния объектов для существующих за пределами завода.
Обратите внимание, что вам может понадобиться сделать это как на входе, так и на выходе, поскольку это может привести к утечке.
Одним из способов обеспечения этого было последовательны бы использовать функцию декоратора:

function decorate(func) { 
    return function() { 
     const argumentsCopy = _.map(arguments, a => angular.copy(a)); 
     const result = func.apply(factory, argumentsCopy); 
     return angular.copy(result); 
    }; 
} 

... который в свою очередь, используется так:

var factory = { 
    setInternatioanl: decorate(_setInternational), 
    setTripType: decorate(_setTripType), 
    setJourneys: decorate(_setJourneys), 
    getConfigs: decorate(_getConfigs) 
} 
return factory 
+0

Ваше решение работает просто отлично! Почему вы использовали функцию apply и передали завод, так как это первый аргумент? –

+1

Это гарантирует, что ключевое слово 'this' продолжает ссылаться на завод, как и ожидалось. Кроме того, он корректно раскладывает массив 'argumentsCopy'. Если есть, если ваши функции использовали 'this' или имели несколько входных аргументов, вы могли бы заметить разницу больше. –

0

Вы можете использовать ключевое слово new, чтобы иметь разные экземпляры службы.

Что-то вроде, var searchEngineConfigs = new SearchEngineConfigs();, а затем использовать его для вызова заводских методов.

Или вы можете использовать angular.copy(), установив переменные в своей службе, чтобы удалить ссылку, которая вызывает обновление в службе.

Что-то подобное,

var _setInternational = function(val) { 
    configs.isInternational = angular.copy(val); 
} 
Смежные вопросы