Angular 1.6:在范围函数执行之前不显示数据
Angular 1.6: Data not showing until scope function execute
标题可能听起来有点奇怪,但事实就是如此。
代码:
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>
问题:未显示来自 table 的数据。奇怪的是,它仅在按下 header 中的按钮并调用该函数时才会显示。
来自服务的数据正确。
更新:租户服务
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;
}]);
我觉得问题是data.tenants.map
returns你新建了一个数组。您不保存对它的引用。
你试过这样做吗
$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)
在收到响应并操作数据后添加 $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
希望对你有帮助
标题可能听起来有点奇怪,但事实就是如此。
代码:
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>
问题:未显示来自 table 的数据。奇怪的是,它仅在按下 header 中的按钮并调用该函数时才会显示。
来自服务的数据正确。
更新:租户服务
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;
}]);
我觉得问题是data.tenants.map
returns你新建了一个数组。您不保存对它的引用。
你试过这样做吗
$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)
在收到响应并操作数据后添加 $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
希望对你有帮助