如何在模型绑定之前延迟角度动画

时间:2015-03-05 18:46:13

标签: javascript ajax angularjs animation

我正在开发一个angularJS项目,我在状态转换之间进行动画制作。我使用了角度wiki作为指导,包括这个plunkr:

http://plnkr.co/edit/NsZhDL?p=preview

我正在从一个<table>动画到下一个状态的<table>动画(它是向右滑动),工作正常,但动画会在加载数据之前触发。因此,单行标题从右侧滑入,然后数据加载到<tr>中。在我的控制器中,我有一个ajax调用,可以获取数据。在动画开火之后,它显然会得到它。有没有办法确保在动画之前加载数据?

function CategoryList(/*dependencies*/) {
var controller = this;
//setup stuff

//get the data
$http.get('/My/Url', {
    headers: {
        ShowLoading: true
    }
}).success(function (data, status, headers, config) {
    controller.setCategories(data);
});

我在我的状态对象中尝试过的一件事是使用resolve来获取数据,然后返回一个promise,但结果是一样的。这是尝试:

.state('myStateName', {
            url: '/myUrl/{id:int}',
            templateUrl: '/mytemplate.html',
            controller: 'ListController',
            controllerAs: 'List',
            resolve: {
                ajaxData: ['$q', '$http', '$stateParams', '$timeout',
                    function ($q, $http, $stateParams, $timeout) {
                        var deferred = $q.defer();
                        // $http returns a promise for the url data
                        $http.get('/Admin/Activities/Category/GetDetail/' + $stateParams.id, {
                            headers: {
                                ShowLoading: false
                            }
                        }).success(function (data) {
                            deferred.resolve(data);
                        }).error(function (data) {
                            deferred.reject();
                        });
                        return deferred.promise;
                    }]
            }

再次数据恢复正常,它只是在动画之后发生。我认为这样可行,因为在wiki中它说“在实例化控制器之前,必须解决下面解决的每个对象(通过deferred.resolve(),如果它们是一个promise)。”https://github.com/angular-ui/ui-router/wiki#resolve

编辑经过一些研究后,我认为ajax在动画之前完成,但模型绑定发生在之后。我相信这是当前的一系列事件。

  1. 点击州过渡链接
  2. 解决火灾,从服务器获取数据
  3. 获取目标州的模板
  4. 将新模板动画放置到位([ui-view] -enter yada yada)
  5. 将新模板绑定到模型。
  6. 编辑这是一个CSS问题,表格div父级的最小高度设置为1px,这导致tbody在动画结束前不显示。

2 个答案:

答案 0 :(得分:0)

此时Plunker目前还没有工作,但这似乎有效:

    var myapp = angular.module('myapp', ["ui.router", "ngAnimate"]);

    function dummyResolve(data) {
      return function ($timeout, $q) {
        var defer = $q.defer();
        $timeout(function () {
          defer.resolve(data);
        }, 500);
        return defer.promise;
      };
    }

    myapp.config(function ($stateProvider, $urlRouterProvider) {
      $stateProvider
        .state("foo", {
          url: "/foo",
          template: '<h1>{{ data }}</h1>',
          controller: 'FooBarCtrl',
          resolve: {
            data: dummyResolve('foo')
          }
        })
        .state("bar", {
          url: "/bar",
          template: '<h1>{{ data }}</h1>',
          controller: 'FooBarCtrl',
          resolve: {
            data: dummyResolve('bar')
          }
        })

      $urlRouterProvider.otherwise("/foo");
    });

    myapp.controller('FooBarCtrl', function ($scope, data) {
      $scope.data = data;
    });

动画在数据解析后发生。

答案 1 :(得分:0)

所以最初决心让我困惑,因为我的生活无法让它正常工作。

以下是我正在使用的项目中使用的代码,此代码有效...

var getUserData = ['$q','$http',
  function($q, $http) {
    var deferred = $q.defer();

    // You can run the code that starts your animation here, not sure how it works.
    $http.get('url')
      .success(function(data) {
        // Once it hits here it means you have your data and the resolve will complete allowing the state to change.
        // If you need your animation to run now, you would add it here
        deferred.resolve(data);
      }
      .error(function(data) {
        deferred.reject();
      }

    return deferred.promise;
  }]

希望这有帮助,如果您需要澄清,请告诉我

因此,要将解析数据提供给目标状态控制器,您只需将其注入控制器

app.controller('someController', ['$scope', 'resolvedData',
  function($scope, resolvedData) {
    $scope.data = resolvedData // Here is your data
  }]);

请参阅有关解析更多信息的{ui.router文档https://github.com/angular-ui/ui-router/wiki