服务从数据存储区检索数据但不更新ui

时间:2013-07-26 18:52:59

标签: html5 angularjs angularjs-ng-repeat

我有一个从数据存储区(Web SQL)检索数据的服务。然后,它将数据存储在AngularJS数组中。问题是这不会启动对UI的更改。

相反,如果从数据存储区检索数据后,我使用$ get方法调用Web服务并将结果附加到前一个数组,所有数据都会更新UI。

有什么建议吗?是否有可能在Angular绑定变量之前填充数组?

我可以以某种方式延迟服务的执行吗?

大多数代码都取自以下示例:http://vojtajina.github.io/WebApp-CodeLab/FinalProject/

2 个答案:

答案 0 :(得分:1)

为了让UI神奇地更新,必须对$ scope的属性进行一些更改。例如,如果从休息资源中检索一些用户,我可能会这样做:

app.controller("UserCtrl", function($http) {
  $http.get("users").success(function(data) {
    $scope.users = data; // update $scope.users IN the callback
  }
)

虽然在加载模板之前有更好的方法来检索数据(通过routes / ng-view):

app.config(function($routeProvider, userFactory) {
  $routeProvider
    .when("/users", {
      templateUrl: "pages/user.html",
      controller: "UserCtrl",
      resolve: {
        // users will be available on UserCtrl (inject it)
        users: userFactory.getUsers() // returns a promise which must be resolved before $routeChangeSuccess
    }
  }
});
app.factory("userFactory", function($http, $q) {
  var factory = {};
  factory.getUsers = function() {
    var delay = $q.defer(); // promise
    $http.get("/users").success(function(data){
      delay.resolve(data); // return an array of users as resolved object (parsed from JSON)
    }).error(function() {
      delay.reject("Unable to fetch users");
    });
    return delay.promise; // route will not succeed unless resolved
  return factory;
});
app.controller("UserCtrl", function($http, users) { // resolved users injected
  // nothing else needed, just use users it in your template - your good to go!
)

我已经实现了两种方法,后者很可取,原因有两个:

在资源解析之前,它不会加载页面。这允许您通过在$ routeChangeStart和$ routeChangeSuccess上附加处理程序来放置加载图标等。

此外,它通过“输入”动画更好地发挥作用,每次加载页面时,所有项目都不会烦人地播放输入动画(因为$ scope.users是预先填充的,而不是在回调中更新一旦页面加载了。)

答案 1 :(得分:1)

假设您要将数据分配到array中的controller,请在更新后设置$scope.$apply()

例如:

$scope.portfolio = {};

$scope.getPortfolio = function() {
    $.ajax({
        url: 'http://website.com:1337/portfolio',
        type:'GET',
        success: function(data, textStatus, jqXHR) {
            $scope.portfolio = data;
            $scope.$apply();
        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log(errorThrown);
        }
    });     

};