【问题标题】:How is the best way to update $scope after fetching data from service in AngularJS从 AngularJS 中的服务获取数据后更新 $scope 的最佳方法是什么
【发布时间】:2014-11-05 12:15:22
【问题描述】:

我正在使用 angularJS 开发一个小应用程序,该应用程序使用对 API 服务的调用来获取、显示和操作数据。

一开始一切都很顺利和简单,但是当我不得不在不同控制器下的应用程序的不同部分显示相同的数据时,我开始将所有 API 调用转移到一个工厂以共享该数据和控制,而不是制作另一个如果不需要,请请求。

但随之而来的是一个不同的问题:发出请求,将数据放入适当的 $scope,但在我手动单击某处以与视图交互之前,视图中不会反映任何更改。

我一直在尝试使用 $scope.$apply 和 $scope.$watch;我设法让它发挥作用,但现在我发现自己在很多地方都使用了延迟,这对我来说似乎很不自然。

例如,我将向您展示用户配置文件的代码,以了解我在说什么。

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

<title>Demo</title>
</head>
<body ng-app="app" ng-controller="DashboardCtrl">

<div ng-init="getOwnProfile()">
  <h1>My account</h1>

  <form class="inline-form" role="form">
      <input type="hidden" value="2" name="id"/>

      <div class="form-group has-error">
          <ul class="input-grp-2">
              <li><input name="first_name" type="text" ng-model="profile.first_name" placeholder="First name" /></li>
              <li><input name="last_name" type="text" ng-model="profile.last_name" placeholder="Last name" /></li>
          </ul>
      </div>
      <input name="phone" type="text" ng-model="profile.phone" placeholder="Phone number"/>

      <textarea name="information" rows="7">{{ profile.information }}</textarea>

      <a href="#" class="button btn-add-photo"><span class="glyphicon glyphicon-camera"></span> Add Photo</a>
      <input style="display: none" type="file" name="image" class="upload-photo" id="input_upload" accept="image/*"/>
  </form>
  <a href="" target="_self" class="button btn-green" ng-click="updateProfile(profile)">Submit Changes</a>

</div>

<script src="/js/app.js"></script>
<script src="/js/controllers/dashboard.js"></script>
<script src="/js/api.js"></script>
</body>
</html>

我使用的仪表板控制器:

$scope.profile = null;

$scope.getOwnProfile = function () {
    $scope.$watch( 'profile', function() {
        setTimeout(function () {
            $scope.$apply(function () {
                $scope.profile = API.getOwnProfile();
            });
        }, 100);
    })
};

API 服务将配置文件设置为:

var APIService = {};

var ownProfile;

APIService.resetRenterProfile = function() {
    ownProfile = undefined;
};

APIService.getOwnProfile = function() {
    if (typeof ownProfile === 'undefined') {
        retrieveOwnProfile();
    }
    return ownProfile;
};

retrieveOwnProfile = function() {
    return Restangular.one('profile', null).get()  // GET: /profiles
        .then(function (profile) {
            ownProfile = profile;
        });
};

return APIService;

正如我所说,这可行,但我有两个问题。

1) 为每个控制器获取数据并将其放入正确范围内的正确 var 中,但是在用户做出对视图有影响的操作之前,视图中不会显示任何 $scope 数据,例如单击下拉菜单、选项卡等。

2) 我必须指定以毫秒为单位的延迟,如果出于任何原因,对后端的 API 调用花费的时间超过了该延迟,则 $scope 数据在用户手动与视图交互之前不会显示。

尽管它有效,但我觉得我做错了,所以我希望有人能指出我如何避免或改善这类问题。

非常感谢。

【问题讨论】:

    标签: javascript angularjs service scope angularjs-scope


    【解决方案1】:
    $scope.getOwnProfile = function () {
        $scope.profile = API.getOwnProfile();
    };
    
    retrieveOwnProfile = function() {
        ownProfile = $resource('profile').get();
    };
    

    上面的代码可以按你的意愿工作......为什么? 在浏览器中调试,看看你执行时会发生什么: var 结果 = $resource().get(); 您可以看到“结果”不是通常的对象。并且 angularjs 本身会在“结果”更新后立即更新视图。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多