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

标签 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

我可以创建以 $ 开头的属性吗?像其他属性一样显示?

最佳答案

基本上你不能。它被“硬编码”到过滤器的行为中。
尽管如此,构建一个自定义 JSON 过滤器非常容易,该过滤器的行为与 Angular 的过滤器相同,但不会过滤掉以“$”开头的属性。

(进一步向下滚动查看示例代码和 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);
}

这个函数利用了“原生” JSON.stringify() 函数,传递自定义替换函数( toJsonReplacer )。
toJsonReplacer()函数处理一些特殊情况:它检查 key 是否以 $ 开头。如果是,则忽略它(这是我们要更改的内容),并检查该值是 Window、Document 还是 Scope 对象(在这种情况下,它将其转换为描述性字符串以避免“转换循环JSON 结构”错误)。
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 的进一步改进/增强中受益。过滤器,因此您必须重新定义您的过滤器以合并更改。当然,对于像这样一个基本而简单的过滤器,不应期望频繁或广泛的更改,但这并不意味着不会有任何更改。

关于json - 我可以阻止 Angular.js 的 json 过滤器排除以 $ 开头的属性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22832906/

相关文章:

javascript - 如何解决在 JSON 文件中创建新对象的问题?

node.js - 无法更新 mongodb 中的单个数据

c# - 我应该如何解析 JSON,它的键和值的重音被转义而不影响字段值中的转义?

java - 如果 JsonGenerator 是在 ByteArrayOutputStream 之上创建的,那么关闭它是否有意义

javascript - 使用 Angular 将字符串中编码的 HTML 转换为输入字段的纯文本

angularjs - 在 Angular4 中-如何添加 lodash 并进行无错误的构建

javascript - AngularJS UI Bootstrap 模式无法执行范围内的功能

javascript - Bootstrap 模式无法在 jsfiddle 中打开

AngularJs 如何在 Angular UI Bootstrap 分页中显示过滤结果

javascript - ng-重复日期范围过滤器