【问题标题】:Modify source data for ng-repeat修改 ng-repeat 的源数据
【发布时间】:2019-11-16 00:58:46
【问题描述】:

我有一个与以下示例类似的应用程序,但我无法弄清楚源数据未更新的原因。更多信息在示例 cmets 中。我确定这是我忽略的一些小问题。

控制器

    $scope.items = [
        { id: 1, color: 'red', title: 'car' },
        { id: 2, color: 'blue', title: 'sky' },
        { id: 3, color: 'transparent', title: 'nothing' }
    ]
    $scope.favoriteIds = [1, 2, 3]
    $scope.getItem = function(id) { /* returns an item with given id */ }

最后,有两种方法可以修改$scope.items,但只有第一种有效,因为新项目获得了not-already-known id。 p>

    $scope.changeData1 = function() {
        $scope.items = [{ id: 666, color: 'ugly', title: 'face' }]
        $scope.favoriteIds = [666]
    }

    $scope.changeData2 = function() {
        $scope.items = [{ id: 1, color: 'ugly', title: 'face' }]
        $scope.favoriteIds = [1]
    }

查看

<h1>Favourite items</h1>

<ul ng-repeat="id in favoriteIds" data-ng-init="item = getItem(id)">
    <li>I like my {{ item.color }} {{ item.title }}</li>
</ul>

<button ng-click="changeData1()">Modify data</button>
<!-- prints: I like my ugly face -->

<button ng-click="changeData2()">Modify nothing</button>
<!-- prints: I like my red car -->

问题是,我需要使用第二种方式来修改数据。

http://jsfiddle.net/4pEpN/7/

【问题讨论】:

    标签: javascript angularjs angularjs-ng-repeat


    【解决方案1】:

    我对 Angular 也比较陌生,所以如果有一种简单的方法可以做到这一点,我不知道它是什么(不幸的是,Angular 文档很糟糕)。无论如何,您可以通过重新考虑代码的结构来避免这种情况(您最终也会得到一个更好的程序)。

    在您看来,在 ng-repeat 循环的每次迭代期间,您使用 ng-initid 上调用 getItem。这就是导致您的问题的原因,并且(显然)是由于 Angular 性能特性(更多信息请参见 this question)。

    基本上,不要使用ng-init,除非在您的应用启动时执行某些操作。否则,您将得到您现在所拥有的:视图(调用getItem(id))而不是它所属的模型中的逻辑。 p>

    改为使用ng-repeat 重复您要显示的准确 数据。就像我之前说的,这意味着一些代码重新排列。例如,您可以使用函数动态生成用户当前的项目列表。看看这个小提琴:http://jsfiddle.net/4pEpN/19/

    查看我在该代码中的 cmets 了解我所做的所有更改,但最相关的是:

    $scope.favoriteItems = function() {
        var favObjs = [];
        for (var i = 0; i < favoriteIds.length; ++i) {
            favObjs.push(getItem(favoriteIds[i]));
        }
        return favObjs;
    };
    

    那么在你看来:&lt;ul ng-repeat="item in favoriteItems()"&gt;


    您还可以使用许多其他方法。例如,您可以有一个update 函数,它处理任何用户输入后可能需要完成的任何事情(包括更新用户的自定义项目数组)。然后你可以在你的 changeData 函数中调用它。

    【讨论】:

    • 谢谢。最后,我将两个数据集合合并为一个,然后对其进行迭代。它开始导致一个小问题,因为每次数据更改都会多次调用生成函数(如本例中的favoriteItems())。幸运的是,这可以通过$scope.$watch 妥善处理,因此我将favoriteItems 保留为数组并使用$watch 来触发更新事件。
    【解决方案2】:

    我认为ng-init 不合适,因为它只影响模板初始化。 那么如何调用您的getItem(id) 来获取每个属性,如下所示: http://jsfiddle.net/JrvbD/1/

    【讨论】:

    • 感谢您的回答,我同意不当使用ng-init。不幸的是,在一个真实的应用程序中,模板比这个例子复杂得多,所以多次调用getItem(id) 对性能没有好处。
    • 嗯,我会建议在不重复调用的情况下执行此操作的正确方法是在 ng-repeat 的表达式中添加基于 favoriteIds 的过滤器。但是在测试中,看起来 Angular 将过滤器视为静态的,并且实际上只是在观察它的输入。您可以看到我上一个 jsfiddle 的 /2/,但尝试注释掉对项目的更改,您会发现它并没有真正关注过滤器。
    猜你喜欢
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多