【问题标题】:Adding a property to an Angular object向 Angular 对象添加属性
【发布时间】:2015-09-15 22:07:45
【问题描述】:

我正在运行一个从 Web API 服务中提取数据的 Angular 应用程序。 API 将对象作为 JSON 返回,Angular 服务(通过 $http.get() )将它们作为对象数组返回给控制器。很正常的东西。

我想做的是为每个返回的对象添加一个名为“Selected”的属性。此属性纯粹用于 GUI 目的(对象是否在 UI 中被选中)并且不需要以任何方式持久化。我认为最简单的方法是遍历返回的对象数组并添加它。所以我的代码如下所示:

function getData() {
    myService.getData()
        .then(function(data) {
            $scope.myData = data.results;
            // Add a "Selected" property to each object
            $.each($scope.myData, function(item) {
                item.Selected = false;
            });
}

当它到达“item.Selected = false”的行时,它会抛出一条错误消息,说“无法分配给只读属性 Selected”。

我不清楚为什么“选定”是只读的?我不知道 Angular 在读取数据时是否会进行一些时髦的对象处理?我在这里做错了什么?还是我应该以完全不同的方式来处理这个问题?

注意(我想避免使 Selected 成为原始对象的一部分,因为它不代表与该对象相关的任何内容)。

【问题讨论】:

  • 你确定你有正确的数据吗?当使用strict mode(我希望你是)时,尝试将属性分配给原始值(例如字符串或布尔值)将引发此错误。
  • 能否确认分配$scope.myData = data.results;后,$scope.myData确实是预期的数组?
  • 如果您只在 UI 中使用 selected 并且始终默认为 false,那么为什么要设置它呢?选中时设置为true,取消选中时设置为false。
  • 不是一个答案,但我想分享我用来处理将视图特定属性添加到从服务器获取的数据的模式。示例:假设您正在接收用户实体的数组。然后创建一个User Model 类,该类在构造函数中需要用户实体对象,并通过可以引用原始属性的entity 属性公开它。然后通过带有任何附加属性的“原型”进行扩展。类似方法:medium.com/opinionated-angularjs/…
  • 检查 $.each 的使用情况,它在遍历数组时返回的第一个参数是索引,第二个是项目。索引是 int,这是不允许添加属性的。 api.jquery.com/jquery.each/#jQuery-each-array-callback

标签: javascript angularjs object


【解决方案1】:

要向对象添加属性,请使用underscorejs

"each _.each(list, iteratee, [context]) 别名:forEach 遍历元素列表,依次将每个元素生成一个 iteratee 函数。如果传递了一个,则迭代对象绑定到上下文对象。每次调用 iteratee 时都使用三个参数:(元素、索引、列表)。如果 list 是 JavaScript 对象,iteratee 的参数将是 (value, key, list)。返回链表。"

"扩展 _.extend(目的地, *来源) 将源对象中的所有属性复制到目标对象,然后返回目标对象。它是有序的,因此最后一个源将覆盖先前参数中的同名属性。”

$scope.myData = data.results;
// Add a "Selected" property to each object   

_.each($scope.myData, function(ent) {
    _.extend(ent, {
        Selected : false
    });
});

【讨论】:

    【解决方案2】:

    你的调试器 screenshot 实际上给你一个比你发布的更有用的错误信息(强调我的):

    无法分配给只读属性“已选择”0

    这表明,您得到的不是对象,而是一个数字作为您的 item 变量(在本例中为 0)。在严格模式下将属性分配给基元会引发此“无法分配给只读属性”错误。 (没有严格模式,它只是默默地失败。)

    正如JcT 在评论中指出的那样,这是因为$.each 调用函数时传递了2 个参数,首先是索引,其次是值。见documentation of $.each

    回调

    类型:函数(整数 indexInArray,对象值)

    因此,即使您将参数命名为 item,它也会收到当前索引的值。这意味着只需将缺少的第一个参数添加到回调中即可修复您的代码,如下所示:

    function getData() {
        myService.getData()
            .then(function(data) {
                $scope.myData = data.results;
                // Add a "Selected" property to each object
                $.each($scope.myData, function(index, item) { //index was added here!
                    item.Selected = false;
                });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-14
      • 2013-03-06
      相关资源
      最近更新 更多