AngularJS过滤/添加属性到对象

时间:2016-03-29 14:36:33

标签: angularjs filter

我有一个对象数组,每个对象都有一个电子邮件发件人属性,例如我的sender{sender@demo.abc}。现在我想填写一个包含2个值的表:1)名称(“我的发件人”)和2)地址(“sender@demo.abc”)。

目前我使用过滤器将2个新属性添加到我的对象并使用ng-repeat渲染它。我现在的问题是我收到错误

  

[$ rootScope:infdig]

(但渲染结果很好)。我google了一下,问题可能是我在我的过滤器中创建了一个新数组,并且属性长度与ng-repeat对象长度不匹配。

我是angularjs的新手,我不确定我是否完全错误地使用了滤镜,而且我想要的解决方案有更多的方法?

演示代码JS:

demoApp.filter("customFilter", function () {
return function (input) {
    var result = [];
    if (input && input.length && input.length > 0) {
        for (var i = 0; i < input.length; i++) {
            var senderName = "";
            var senderDomain = "";
            var both = input[i].Name;

            both = both.split("").reverse().join("");
            senderName = both.substring(both.indexOf("<") + 1).split("").reverse().join("");
            senderDomain = both.substring(1, both.indexOf("<")).split("").reverse().join("");

            var domainBeforeAt = senderDomain.split("@")[0];
            var domainAfterAt = senderDomain.split("@")[1];

            var output = {
                "customId": i,
                "displayName": senderName,
                "domain": {
                    "full": senderDomain,
                    "beforeAt": domainBeforeAt,
                    "afterAt": domainAfterAt,
                }
            }

            result.push(output);
        }
    }

    return result;        
}
});

演示代码HTML:

<div ng-repeat="sender in list.Sender | customFilter track by $index">

1 个答案:

答案 0 :(得分:1)

更新:为了满足过滤器中访问嵌套对象的要求,我改变了过滤器返回输出的方式。

.filter("customFilter", function () {
  return function (input, params) {
    ...
    var args = Array.prototype.slice.call(arguments);
    var toReturn = output;
    for (var i = 1; i < args.length; i++) {
      toReturn = toReturn[args[i]];
    }
    return toReturn;
 };
});

如果不使用eval,要返回output.domain.full,您必须将嵌套对象的级别作为参数传递给过滤器,例如:

<td class="col-xs-6">{{sender.Name | customFilter:'domain':'full'}}</td>

所以,我认为您的问题源于您想要在ng-repeat中跟踪$ index,而不是在过滤器中。在ng-repeat内设置div指令后,传入过滤器的是数据集中的每个发件人,而不是阵列中的所有发件人,因此您不需要在输入上运行for循环。

我在下面的代码段中完成的一种方法是将要显示的参数(名称,电子邮件)传递到过滤器中,并获取过滤器输出的对象的属性。另一种方法是创建一个单独的名称和电子邮件过滤器并单独应用它们,但是你会以这种方式重复很多代码。

angular.module('demoApp', [])
.controller('SenderListCtrl', function() {
  var ctrl = this;
  
  ctrl.Sender = [
    {
      Name: "my sender<sender@demo.abc>",
      Age: 21
    },
    {
      Name: "another sender<anothersender@demo.abc>",
      Age: 37
    },
    {
      Name: "yet another sender<yetanothersender@demo.abc>",
      Age: 28
    } 
  ];
})
.filter("customFilter", function () {
  return function (input, params) {
    
    if (input && input.length && input.length > 0) {
      var senderName = "";
      var senderDomain = "";
      var both = input;
      
      senderName = both.substring(0, both.indexOf("<"));
      senderDomain = both.substring(both.indexOf("<")+1,both.indexOf(">"));
 
      var domainBeforeAt = senderDomain.split("@")[0];
      var domainAfterAt = senderDomain.split("@")[1];
      var output = {
        name: senderName,
        email: senderDomain,
        domain: {
          full: senderDomain,
          beforeAt: domainBeforeAt,
          afterAt: domainAfterAt,
        }
      };
      var args = Array.prototype.slice.call(arguments);
      var toReturn = output;
      for (var i = 1; i < args.length; i++) {
        toReturn = toReturn[args[i]];
      }
      return toReturn;    
    };
  };
});
<!DOCTYPE html>
<html ng-app="demoApp">

  <head>
    <link data-require="bootstrap-css@3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
    <script data-require="angular.js@1.5.0" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
    <script data-require="bootstrap@3.3.6" data-semver="3.3.6" src="bootstrap-js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-controller="SenderListCtrl as list">
    <table>
      <thead>
        <tr>
          <th class="col-xs-6">Name</th>
          <th class="col-xs-6">Email</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="sender in list.Sender track by $index">
          <td class="col-xs-6">{{sender.Name | customFilter:'name'}}</td>
          <td class="col-xs-6">{{sender.Name | customFilter:'domain':'full'}}</td>
        </tr>
      </tbody>
    </table>
  </body>

</html>

干杯!