我目前正在将指令中存在的两种方法重构到服务中。

这是方法一:

scope.computeStyle = (component) ->
  elementHash = {}
  if component.element.type == 'table'
    elementHash.height = 600
    if component.height?
      elementHash.height = component.height * 50
  else if component.element.type == 'single_value'
    elementHash.height = 200
    elementHash.width = 800
  return elementHash


这是方法二:

scope.computeStyle = (element, rowComponent) ->
  elementHash = {}
  if element.type == 'table'
    elementHash.height = 600
    if rowComponent?.height?
      elementHash.height = rowComponent.height
  else if element.type == 'single_value'
    elementHash.height = 200
    elementHash.width = 800
  return elementHash


他们都做相同的事情(略有不同)。它们采用element/component(包含与我的应用程序中的对象有关的数据的对象),检查它们是什么类型的对象(在这种情况下,是表还是单个值),并应用高度和/或宽度转换。

在我的服务范围内,这是我所做的:

angular = require "angular"

angular.module("myapp.dashboards.layouts").service("DashboardLayoutComputeStyle" ->

  @computeStyle = (componentElement, height) ->
    elementHash = {}
    if componentElement.type == 'table'
      elementHash.height = 600
      if height?
        elementHash.height = height
    else if element.type == 'single_value'
      elementHash.height = 200
      elementHash.width = 800
    return elementHash

  @
)


这是我的问题所在:

我不确定我抽象的方法在这一行要做什么:

  if height?
    elementHash.height = height


在方法一中,它是这样的:

    if component.height?
      elementHash.height = component.height * 50


在方法二中,它是这样的:

    if rowComponent?.height?
      elementHash.height = rowComponent.height


对于这两行的重构,我有三个约束:


我必须检查方法2中是否同时存在rowComponentheight
我不需要检查component是否存在,但是我必须检查方法1中是否存在height
在方法一中,我必须将elementHash,height设置为component.height * 50,而在方法二中,我只需将rowComponent.height分配给elementHash.height


我如何抽象这两行?

最佳答案

这是一个令人困惑的场景,所以我尝试将其分解-如果我对它的工作方式有任何疑问,请纠正我。我正在使用您的两个原始功能,而不是您的组合版本。


有2个函数,但是它们都有一个共同的大小写(single_value),因此实际上我们可以取出这个共同的项目,并且我们有3个不同的大小写(single_valuetablerowComponent
在第二个函数中,仅为了检查类型,将元素与rowComponent一起传递。因此,相反,我会选择第二个变量,它是一个可选的类型参数。如果未提供,它将使用元素中的类型,并且将与方法1一样工作
由于每个顶层if语句均基于元素的类型,因此我将其更改为更清晰的case语句




  @computeStyle = (element, type) ->
    # if no type is supplied, use the element's type
    type ?= element.type
    elementHash = {}
    switch type
      when 'rowComponent'
        elementHash.height = if element?.height?
          rowComponent.height
        else
          600
      when 'table'
        elementHash.height = if component.height?
          component.height * 50
        else
          600
      when 'single_value'
        elementHash.height = 200
        elementHash.width = 800
    elementHash


现在,您以前调用method1的地方可以使用computeStyle(element),使用method2的地方可以使用computeStyle(rowComponent, element.type)

=编辑=
根据OP的评论,没有类型可以标识rowComponent,我提出了一个替代解决方案



  @computeStyle = (element, rowComponent) ->
    elementHash = {}
    # check the second argument to decide if we have a rowComponent or not
    if element.type is table and rowComponent?
      elementHash.height = if rowComponent.height?
        rowComponent.height
      else
        600
    # otherwise check the first elements type
    else
      switch element.type
        when 'table'
          elementHash.height = if component.height?
            component.height * 50
          else
            600
        when 'single_value'
          elementHash.height = 200
          elementHash.width = 800
    elementHash

09-18 08:54