我可以阻止Angular.js的json过滤器排除以$开头的属性吗?

时间:2014-04-03 09:10:39

标签: json angularjs angularjs-filter

Angular.js有一个方便的内置过滤器json,它将JavaScript对象显示为格式良好的JSON。

但是,它似乎过滤掉默认情况下以$开头的对象属性:

模板:

<pre>{{ {'name':'value', 'special':'yes', '$reallyspecial':'Er...'} | json }}</pre>

显示:

{
  "name": "value",
  "special": "yes"
}

http://plnkr.co/edit/oem4HJ9utZMYGVbPkT6N?p=preview

我可以将以$开头的属性显示为与其他属性一样吗?

1 个答案:

答案 0 :(得分:6)

基本上你不能。这是&#34;硬编码&#34;进入过滤器的行为 尽管如此,构建一个自定义JSON过滤器非常容易,该过滤器的行为与Angular相同,但不会过滤掉以&#39; $&#39;开头的属性。

(向下滚动查看示例代码和 short demo 。)


如果您查看 1.2.15 version source code ,您会发现json过滤器定义如下:

function jsonFilter() {
  return function(object) {
    return toJson(object, true);
  };
}

因此,它使用toJson()函数(第二个参数(true)意味着:很好地格式化我的JSON )。


所以,我们的下一站是toJson()函数,如下所示:

function toJson(obj, pretty) {
  if (typeof obj === 'undefined') return undefined;
  return JSON.stringify(obj, toJsonReplacer, pretty ? '  ' : null);
}

此功能使用&#34; native&#34; JSON.stringify() 函数,传递自定义替换函数(toJsonReplacer)。


toJsonReplacer()函数处理一些特殊情况:它检查密钥是否以$开头并忽略它(如果它是这样)(这是我们想要更改的)并检查该值是否为窗口,文档或范围对象(在这种情况下,它将其转换为描述性字符串,以避免&#34;将循环结构转换为JSON&#34;错误)。

function toJsonReplacer(key, value) {
  var val = value;

  if (typeof key === 'string' && key.charAt(0) === '$') {
    val = undefined;
  } else if (isWindow(value)) {
    val = '$WINDOW';
  } else if (value &&  document === value) {
    val = '$DOCUMENT';
  } else if (isScope(value)) {
    val = '$SCOPE';
  }

  return val;
}

为了完整起见,检查Window和Scope的两个函数如下所示:

function isWindow(obj) {
  return obj && obj.document && obj.location && obj.alert && obj.setInterval;
}

function isScope(obj) {
  return obj && obj.$evalAsync && obj.$watch;
}

最后,我们需要做的就是创建一个使用完全相同代码的自定义过滤器,唯一的区别是我们toJsonReplacer()不会过滤掉以$开头的属性。

app.filter('customJson', function () {
    function isWindow(obj) {
        return obj && 
               obj.document && 
               obj.location && 
               obj.alert && 
               obj.setInterval;
    }

    function isScope(obj) {
        return obj && 
               obj.$evalAsync && 
               obj.$watch;
    }

    function toJsonReplacer(key, value) {
        var val = value;

        if (isWindow(value)) {
            val = '$WINDOW';
        } else if (value && (document === value)) {
            val = '$DOCUMENT';
        } else if (isScope(value)) {
            val = '$SCOPE';
        }

        return val;
    }

    function toJson(obj, pretty) {
        if (typeof obj === 'undefined') { return undefined; }
        return JSON.stringify(obj, toJsonReplacer, pretty ? '  ' : null);
    }

    return function(object) {
        return toJson(object, true);
    };
});

另请参阅此 short demo


<子> *缺点是您的自定义JSON过滤器无法从Angular json过滤器的进一步改进/增强中受益,因此您必须重新定义您的更改。当然,对于像这样的基本和简单的过滤器,人们应该期望频繁或广泛的变化,但这并不意味着不会有任何变化。