web-dev-qa-db-ja.com

AngularJS:$ scope.array.Push()は、$ applyでもビューを更新しません

私はAngularJSを学ぼうとしていますが、理解できないこのことがあります。これは、すべてのインターネットが$scope.$apply、しかし、私はすでにそれを使用していて、何もしません。

基本的に、私はTwitter APIを使用してタイムラインを取得し、下からスクロールすると、より多くのツイートを読み込みます。この部分は機能します。私はそれを行うためにファクトリを使用していますが、コンソールでオブジェクト受信を表示できます。ここでは問題はありません。

データを表示するには、次のようなビューがあります。

<div class='timeline' ng-controller='TimelineCtrl' is-scrolled='loadData()'>
    <div class='Tweet' ng-repeat='p in posts'>
        <img class='portrait' src='{{p.user.profile_image_url}}' />
        <p>{{p.text}}</p>
        <p class='date'>{{p.created_at}}</p>
    </div>
</div>

私のコントローラーは次のようになります。

    $scope.posts = [];

    // Load the original tweets list
    TwitterAPI.timeline($scope.count, function(data) {
        $scope.$apply(function() {
            $scope.maxId = data[data.length-1].id;
            $scope.sinceId = data[0].id;
            $scope.posts.Push(data);
        });
    });

データは合法です。

私がまったく理解していないこと、そしてそれを解決するのは非常に簡単だと思うようにしますが、私はそれを見ていないだけです、「Push(data)」の代わりに「= data」を使用すると、ビューは更新しました。さらにツイートをロードしても、「=」を使用すると、ビューが更新されます(もちろん、コンテンツは置き換えられますが、これは私が望んでいないものです)。

注:maxId、sinceId、およびcountは以前に初期化されていますが、重要ではないと思われるため、そこに配置しませんでした。

12
Mimu

問題は、AngularのNgRepeatsameオブジェクトを複数回繰り返した場合に停止することです。 jsFiddleを作成しました を示しました。

最初のセクションでは、配列に文字列を追加できます。最初のボタンは常に同じ文字列オブジェクトを追加し、2番目のボタンは毎回新しい文字列オブジェクトを作成します。最初のボタンを2回クリックするとすぐに、リストに何を追加してもかまいません。

2番目のセクションでは、すべてのオブジェクトに同じ文字列オブジェクトへの参照が含まれている場合でも、常に新しいオブジェクトを追加します。これは期待どおりに機能します。

したがって、これを明示的な答えにするために、リストに追加するものがdistinctオブジェクトであることを確認し、必要に応じてオブジェクトリテラルを使用してこれを強制します。を好む Array#Push over Array#concat後者は毎回新しい配列オブジェクトを作成します。また、アイテムがたくさんある場合、大量のチャーンとガベージコレクションが発生します。

HTML:

<div ng-controller="Controller1">
    <button ng-click="addLine()">Add Line</button>
    <button ng-click="addNumber()">Add Number</button>
    <button ng-click="reset()">Reset</button>
    <div>{{lines}}</div>
    <div ng-repeat="line in lines">
        {{line}}
    </div>
</div>

<hr />

<div ng-controller="Controller2">
    <button ng-click="addObject()">Add Object</button>
    <button ng-click="reset()">Reset</button>
    <div>{{objects}}</div>
    <div ng-repeat="obj in objects">
        {{obj.data}}
    </div>
</div>

JavaScript:

(function () {
    var myApp = angular.module('myApp', []);

    myApp.controller('Controller1', function ($scope) {
        $scope.lines = [];

        $scope.addLine = function () {
            $scope.lines.Push('Hello world!');
        };

        $scope.addNumber = function () {
            $scope.lines.Push('Line ' + $scope.lines.length);
        };

        $scope.reset = function () {
            $scope.lines = [];
        };
    });

    myApp.controller('Controller2', function ($scope) {
        $scope.objects = [];

        $scope.addObject = function () {
            var obj = { data: 'Hello world!' };
            $scope.objects.Push(obj);
        };

        $scope.reset = function () {
            $scope.objects = [];
        };
    });
})();
10
Chris Bouchard

Ng-repeatをそのように($ indexで追跡して)構造化すると、だまされて止まらないと思います:

<div class='Tweet' ng-repeat='p in posts track by $index'>
...
</div>
6
Geoff Oslund