2014-01-15 36 views
2

编写角度服务时,我发现了一种我认为非常方便的图案。我认为它适合修饰器模式的描述。给定对象的数组:数据对象阵列上装饰图案的替代方案

players = [{ 
    name: 'Fred', 
    counter: 0 
},{ 
    name: 'Fritz', 
    counter: 0 
},{ 
    name: 'Frank', 
    counter: 0 
}]; 

将它传递给视图或控制器之前,我使其通过一个装饰功能:

players.forEach(decorate); 

这个函数增加了方便的方法,每一个对象,允许改变它们在放置,而无需检索对象的索引的:

function decorate(p) { 
    p.reset = function() { 
    this.counter = 0; 
    }; 
    p.increment = function() { 
    this.counter += 1; 
    }; 
    p.bonus = function() { 
    this.counter += 10; 
    }; 
    p.penalty = function() { 
    this.counter -= 10; 
    }; 
} 

这是一个没有角也是有用的,但特别是与角它允许简单的事件结合无线薄ng-repeat指令。

<div ng-repeat="player in players"> 
    <div ng-click="player.reset()">reset {{player.name}}</div> 
</div> 

考虑到服务可能被多个控制器引用,简化接口对代码的结尾有相当的影响。

撇开性能问题,你看到这种方法的缺点吗?或者你是否看到过一种你认为更好的不同方面的模式(例如使用new)?

+0

你可以看着[混入](HTTP:/ /javascriptweblog.wordpress.com/2011/05/31/a-fresh-look-at-javascript-mixins/)概念。 – Tibos

+0

您可以通过使用原型来提高性能,例如'players = players.map(createInstance)' – Bergi

+0

看起来像修饰器模式 –

回答

1

在您的控制器我有你需要

.service("myService", function(){ 
    this.players = [...] 
    this.reset = function(player){ 
     player.counter = 0; 
    }; 
}); 

function MyController($scope, myService){ 
    $scope.players = myService.players; 
    $scope.reset = function(player){ 
     myService.reset(player); 
    } 
    OR 
    $scope.reset = myService.reset; 
} 

然后在你的HTML只需要调用该函数的不同的功能,而不是

<div ng-repeat="player in players"> 
    <div ng-click="reset(player)">reset {{player.name}}</div> 
</div> 
+0

的情况下编辑这个问题,但是如果模型存在于一个服务中,你希望在同一个服务中定义这些函数来进行封装,在这种情况下,你将不得不重新分配它们到每个想要在控制器中使用它们中的一个的范围变量 – danza

+0

您可以将服务功能直接分配给相同的范围,或者将范围呼叫到服务。无论哪种方式都很好。看看我的编辑 –

+0

是的,但这正是我想要避免的重复类型 – danza