【问题标题】:Items don't show up when ng-repeat is populated in a timeout超时填充 ng-repeat 时项目不显示
【发布时间】:2014-12-18 15:39:53
【问题描述】:

当用户在页面上滚动到元素时,我使用wow.js 为元素设置动画。我已经使用ng-repeat 将一堆元素加载到浏览器中,并且它们在立即加载时动画效果很好。您可以在此演示中看到正确加载的元素:

http://codepen.io/Chevex/pen/eHsCF

但是,当数据异步添加到$scope.items 数组时,它似乎不起作用。

http://codepen.io/Chevex/pen/KvpqB

如果删除.wow 类,您可以看到元素已添加到页面中。 .wow 类隐藏了元素,但 wowjs 并没有显示它们,因为它们出于某种原因出现在页面上。

有什么想法吗?

【问题讨论】:

    标签: javascript angularjs css-animations animate.css wow.js


    【解决方案1】:

    坏消息

    通过反复试验,我发现 WOW's "asynchronous content support" 仅在您调用 new WOW().init(); 时在 DOM 中呈现 wow 元素时才有效。否则它不会同步任何东西。

    证明:

    Not Working Example

    Working Example

    唯一的区别是工作示例中有这个虚拟标签:

    <section class="wow"></section>
    

    Another Working Example based on your code

    因此,如果您希望 WOW 异步工作,只需确保在调用 new WOW().init(); 之前有一个带有“wow”类的虚拟元素即可。

    上一个答案(也很有趣,你可能想看看)

    请看一下this example that I've made for you

    angular.module('wowTest', [])
    .factory('wowAPI', ['$http', function ($http) {
        return {        
            getItems: function () { return $http.get('data.json'); }
        }
    }])
    .controller('wowController', function($scope, wowAPI, $timeout){
      $scope.items = [];
      wowAPI.getItems().success(function(data){
        $scope.items=data.items; 
      }).then(function(){
        $timeout(function(){
          new WOW().init();
        });
      });
    });
    

    the equivalent example with your original code

    var app = angular.module('app', []);
    app.controller('mainCtrl', function ($scope, $timeout) {
      $scope.items = [];
      $timeout(function () {
        for (var count = 0; count < 50; count++) {
          $scope.items.push({
            text: "Item " + count
          });
        }
      }).then(function(){ 
         $timeout(function(){
            new WOW().init();
          });
      });
    });
    

    问题是 WOW 似乎实际上需要在 DOM 渲染后被实例化,因此 $timeout 内的函数确保代码将在 $diggest 循环结束时执行,在你浏览器已经在 DOM 中呈现了您的 $scope 的新值。

    我想你也可以这样做(见下文),但我认为最好将 Promise 链接起来,而不是把一个放在另一个里面:

    .controller('wowController', function($scope, wowAPI, $timeout){
        $scope.items = [];
        wowAPI.getItems().success(function(data){
          $scope.items=data.items; 
          $timeout(function(){
            new WOW().init();
          });
        });
    });
    

    【讨论】:

    • 有趣。你知道为什么会这样吗? Wowjs 应该处理异步添加的元素,但由于某种原因需要在这里重新初始化。
    • @AlexFord 我对 Wowjs 一无所知,但这个例子证明了 Wowjs 的行为不像你所说的那样。通过拨打电话:new WOW().init();$scope.$apply(); 之后我正在做的是触发$diggest 循环,这将确保更新的$scope 将在您的浏览器中呈现,然后我正在初始化哇。 .. 如果这行得通并且前面的代码并不意味着 Wowjs 的行为与您想象的不一样,对不起。
    • @AlexFord 我已经更新了我的答案,这样做更安全,可能更容易理解发生了什么。
    • @AlexFord 您没有将我的答案标记为已接受是有原因的吗?你认为我的回答应该改进吗?你能告诉我你认为它缺少什么吗?谢谢!
    • 原因是因为对 $timeout 的调用已经在进行中,并且当我也调用 $apply 时,控制台在我的应用程序中报告了错误,但由于某种原因在笔示例并非如此。我向你保证,一旦我更深入地研究它,它就会被标记出来。
    猜你喜欢
    • 2016-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多