有角工厂的双向装订

时间:2016-12-12 14:34:47

标签: angularjs

我写了一个Angular工厂来存储一个我需要传递给不同控制器的对象。工厂看起来像这样:

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这个变化仍然会反映到工厂中,因此,在另一个控制器中更新此属性在第一个控制器的同时使用该工厂。我怎样才能避免这种情况发生?当我明确地调用相应的工厂方法时,我只想更改工厂内对象的值。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

您可以使用new关键字来拥有不同的服务实例。

类似于var searchEngineConfigs = new SearchEngineConfigs();,然后使用它来调用工厂方法。

或者,您可以在设置服务中的变量时使用angular.copy()来删除导致服务更新的引用。

类似的东西,

var _setInternational = function(val) {
    configs.isInternational = angular.copy(val);
}