清理控制器内的表达式

时间:2015-05-24 18:34:46

标签: angularjs

我有一个角度应用程序,其数据采用JSON格式,如下所示:

[
    {
        "Name": "Main",
        "Class": "class-o",
        "Base": 150,
        "Growth": 10
    },
    {
        "Name": "Time",
        "Class": "class-r",
        "Base": 1.2,
        "Growth": 0
    },
    {
        "Name": "Value",
        "Class": "class-r",
        "Base": 35,
        "Growth": 3
    },
    {
        "Name": "Value/Time",
        "Class": "class-r",
        "Base": 35,
        "Growth": 3,
        "Mod": 1.2
    }
]

我有一个ng-repeat来循环显示这些数据:

<ul>
    <li ng-repeat="attr in ctrl.Attr">
        <span ng-class="attr.Class">{{attr.Name}}</span> {{(attr.Base+(attr.Growth*(ctrl.level-1)))*(attr.Mod?attr.Mod:1)}} - {{attr.Growth}}
    </li>
</ul>

这些表达式采用base值,并添加growth * level。当级别按预期更改时,这些表达式会实时更新。

我想清理控制器内的表达式来清理我的html。但我面临两个问题:

  1. Value / Time对象是“Time”和“Value”对象的组合,是唯一具有“Mod”值的对象。我一直试图想出一种方法来削减这个额外的对象。我尝试过从“Base”值创建变量,但它们没有以相同的方式绑定,并且在摘要运行时不会更新。

  2. 如上所述,如果我在控制器中创建表达式并将它们绑定到html,它们会显示,但不会使用摘要进行更新。

  3. 如何在控制器中获取适当的表达式,并让它们更新?

    更新 根据评论,我试图将绑定修改为

    {{ctrl.getAttr(Attr.Name)}}
    

    并将此功能添加到我的控制器:

    this.getAttr = function(attr){
        angular.forEach(ctrl.Attr, function(value){
            if(value.Name == attr){
                return value.Base+(value.Growth*(ctrl.level-1));
            }
        });
    }
    

    但页面上没有显示任何内容。

    澄清

    我的第一点是使用Mod值的表达式的位是添加到JSON的自定义属性。导入应用程序的JSON是:

    [
        {
            "Name": "Main",
            "Class": "class-o",
            "Base": 150,
            "Growth": 10
        },
        {
            "Name": "Time",
            "Class": "class-r",
            "Base": 1.2,
            "Growth": 0
        },
        {
            "Name": "Value",
            "Class": "class-r",
            "Base": 35,
            "Growth": 3
        }
    ]
    

    正在控制器中手动添加值/时间部分:

    [
        {
            "Name": "Main",
            "Class": "class-o",
            "Base": 150,
            "Growth": 10
        },
        {
            "Name": "Time",
            "Class": "class-r",
            "Base": 1.2,
            "Growth": 0
        },
        {
            "Name": "Value",
            "Class": "class-r",
            "Base": 35,
            "Growth": 3
        },
        {
            "Name": "Value/Time",
            "Class": "class-r",
            "Base": 35,
            "Growth": 3,
            "Mod": 1.2
        }
    ]
    

    理想的解决方案是计算值/时间并在不修改原始JSON的情况下添加它。

1 个答案:

答案 0 :(得分:1)

可以在视图中保留一些基本逻辑,但如果逻辑与您的应用程序的功能相关 - 而且这种计算有 - 那么建议执行它在控制器中出于代码可检测性,View的可读性以及经常干扰的原因。

因此,创建一个函数,返回给定对象attr的计算值:

<ul>
  <li ng-repeat="attr in ctrl.Attr">
    ...
    {{ctrl.calc(attr)}}
  </li>
</ul>
var vm = this;
vm.level = 10;
vm.calc = function(attr) {
  return (attr.Base + attr.Growth * (vm.level - 1))*(attr.Mod ? attr.Mod : 1);
};

需要注意的另一点是,因为在您的更新中,您尝试创建了getAttr函数,这是$ watchched函数,例如{{doSomething()}}应该非常快 - 几乎是吸气剂 - (并且必须纯净:幂等并且不会产生任何副作用)。因此,强烈建议避免循环或复杂计算,因为它们将在每个摘要周期执行,并可能对性能产生负面影响。