【问题标题】:Angular 1.6: Data not showing until scope function executeAngular 1.6:在执行范围函数之前不显示数据
【发布时间】:2017-06-04 17:57:40
【问题描述】:

标题可能听起来有点奇怪,但就是这样。

代码:

angular.module('app')


.controller('TenantsCtrl', ['$scope', 'tenantsService','$window','loginService', function ($scope, tenantsService, $window, loginService) {
    $scope.mode = "list";
    $scope.g = [];
    $scope.editTenant = {
      firstName: "",
      lastName: "",
      room: "",
      to: "",
      from: ""
    }
    tenantsService.get().then((data) => {
        data.tenants.map((tenant) => {
          tenant.to = new Date(tenant.to).toLocaleDateString('ro-RO')
          tenant.from = new Date(tenant.from).toLocaleDateString('ro-RO')
        });
        console.log(typeof data.tenants);
        $scope.g = data.tenants;
        console.log($scope.g)
      }).catch((reason) => {
        loginService.doLogout();
        if(confirm(`${reason}. Please login`)) {
          $window.location.href="#!/login";
        }
      })
  $scope.showTenantForm = function(tenant) {
    console.log($scope.g)
  }


 }]);

查看:

<div class="page-header">
    <h1>Cazati <button class="btn btn-xs btn-primary" ng-click="showTenantForm()">Cazeaza</button></h1>
</div>
<div class="row"  ng-cloak>
    {{g}}
    <table class="table table-hover">
        <thead>
            <tr>
                <th>Nume</th>
                <th>Camera</th>
                <th>Cazat din</th>
                <th>Cazat pana la</th>
                <th>Cazat de</th>
                <!--<th>Status</th>-->
                <th>Modifica</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="x in g">
                <td>{{x.lastName}} {{x.firstName}}</td>
                <td>{{x.room}}</td>
                <td>{{x.to}}</td>
                <td>{{x.from}}</td>
                <td></td>
                <td>
                    <button type="button" ng-click="editTenant(tenant.id)" class="btn btn-danger btn-xs">Modifica</button>
                </td>
            </tr>
        </tbody>
    </table>
</div>

问题:表格中的数据未显示。奇怪的是,它只有在按下标题中的按钮并调用函数时才会显示。

来自服务的数据正确。

更新:租户服务

angular.module('app')
.service('graphQLService', ['baseUrl', 'loginService', function (baseUrl, loginService) {
  var graphQLService = {};
  graphQLService.sendQuery = function (query, vars) {
    var self = this;
    vars = vars || {};
    return new Promise(function(resolve, reject) {
      // use fetch to get the result
      fetch(baseUrl + '/gql', {
        method: 'post',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          query,
          vars,
          authToken: loginService.getToken()
        })
      })

      .then(function(response) {
        var status = response.status;
        if(status != 401) {
          return response.json().then((res) => {
            resolve(res.data);
          })
        } else {
          reject(response.statusText);
        }
        if(response.status == 401) {

        }
      })
      .catch(reject);
    });
  };
  return graphQLService;
}]);

【问题讨论】:

  • 您是否尝试在$scope.g = data.tenants; 之后添加Scope.$apply()
  • 好的。添加这个可以解决问题。你能解释一下为什么需要吗?也许将其添加为接受它:)
  • 好的,现在就做
  • 你在tenantsService.get()内部的请求中使用标准的$http服务吗?
  • 不。我已经用我称为 graphql 服务的东西更新了这个问题。在 tenantsService.get 我确实返回 graphQLService.sendQuery('query {tenants { id firstName lastName room from to users { username }}}');

标签: angularjs angular1.6


【解决方案1】:

在收到回复并操作数据后添加$scope.$apply(),然后将数据分配给g 范围变量。所以:

$scope.g = data.tenants;
$scope.$apply();

AngularJS 已经在$scope.$apply 方法中封装了很多代码。这是为了触发$scope.$digest 方法,该方法负责刷新相关范围内的所有绑定并更新值和视图。 例如,如果您使用自定义的$http 服务,它会在$scope.$apply 内部执行,因此您不需要显式调用它。 在你的情况下,你没有使用标准的$http,所以你需要手动触发它。

代码在调用另一个函数后可以正常工作,因为 ng-click 也包含在 $apply 中,因此它会刷新范围内的所有绑定。

如果你想了解更多,这是一篇不错的文章:

http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

希望对你有帮助

【讨论】:

  • 非常感谢 :) 感谢您的宝贵时间
【解决方案2】:

我认为问题在于data.tenants.map 会返回一个新数组。您不保存对它的引用。

您是否尝试过这样做

$scope.g = data.tenants.map((tenant) => {
      tenant.to = new Date(tenant.to).toLocaleDateString('ro-RO');
      tenant.from = new Date(tenant.from).toLocaleDateString('ro-RO');
      return tenant;
    });
    console.log(typeof data.tenants);
    console.log($scope.g)

【讨论】:

  • .map 替换当前数组中的元素。还尝试使用 foreach 和单独的 var。没有结果。 $scope.tentantsList 获取它的值,但它没有显示在页面上:(
  • 是数组的map 方法的自定义实现吗?请看mapArraydeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/…方法的参考
  • 不。值得一提:删除“.map”步骤会导致相同的结果。我不认为这会产生问题
  • 地图元素应返回已编辑的元素,该元素将被推送到新数组。我忘记添加了。