【发布时间】:2016-12-16 09:18:52
【问题描述】:
我从服务更新了我的数组,但视图没有更新。
当我打电话给$scope.$apply() 或$scope.$digest 时,它会记录下来
$digest 已经在进行中
这是我的 main.html 文件。 ctrl.flightsTo 是我提到的数组
<md-progress-linear class="md-accent" ng-hide="ctrl.isFlightDataLoaded" mode="indeterminate"></md-progress-linear>
<div class="md-padding">
<md-autocomplete
ng-show="ctrl.isFlightDataLoaded"
md-selected-item="ctrl.selectedItem"
md-selected-item-change="ctrl.selectedItemChange(item)"
md-search-text="ctrl.searchText"
md-items="item in ctrl.querySearch(searchText)"
md-item-text="item.name"
md-min-length="0"
placeholder="Choose a destination">
<md-item-template>
<span md-highlight-text="ctrl.searchText">{{item.name}} - {{item.iata}}</span>
</md-item-template>
</md-autocomplete>
<ul>
<li ng-repeat="flight in ctrl.flightsTo">{{flight}}</li>
</ul>
</div>
这是我的 MainCtrl。
当调用md-selected-item-change 事件时,我在selectedItemChange 函数中从flightDataService 获取我的航班数据。
但 Angular 不会更新视图。
.controller('MainCtrl', function(flightDataService) {
var self = this;
self.isFlightDataLoaded = false;
self.destinations = [];
self.querySearch = querySearch;
self.flightsTo = [];
self.selectedItemChange = selectedItemChange;
self.init = init;
function querySearch(query) {
var results = query ? self.destinations.filter(createFilterFor(query)) : self.destinations;
return results;
};
function createFilterFor(query) {
var lowercaseQuery = angular.lowercase(query);
return function filterFn(destination) {
return angular.lowercase(destination.iata).indexOf(lowercaseQuery) === 0;
}
};
function selectedItemChange(item) {
if (typeof item !== 'undefined') {
self.flightsTo = flightDataService.getFlightsTo(item.iata);
}
};
function init() {
flightDataService.loadAll().then(function() {
self.destinations = flightDataService.getAirports();
self.isFlightDataLoaded = true;
}).catch(function(error) {
console.log(error);
});
};
self.init();
});
最后,我附加了我的 flightDataService。
它只是返回保存的数据。
.factory('flightDataService', function($http, $q, papa) {
var FLIGHT_DATA_URL = 'https://s3-ap-southeast-2.amazonaws.com/glow-dev-assets/flight-data-gz.csv';
var self = this;
self.flights = [];
self.airports = [];
self.routes = [];
self.loadAll = loadAll;
self.getAirports = getAirports;
self.getFlightsTo = getFlightsTo;
function loadAll() {
var deferred = $q.defer();
loadAirportData().then(function(airports) {
loadFlightData().then(function(flights) {
processFlightData(flights, airports);
deferred.resolve();
}).catch(function(error) {
deferred.reject(error);
});
}).catch(function(error) {
deferred.reject(error);
});
return deferred.promise;
};
function loadAirportData() {
var deferred = $q.defer();
$http({
method: 'GET',
url: '/assets/airports.json'
}).then(function(response) {
deferred.resolve(response.data);
}, function(error) {
deferred.reject(error);
});
return deferred.promise;
};
function loadFlightData() {
var deferred = $q.defer();
$http({
method: 'GET',
url: FLIGHT_DATA_URL
}).then(function(response) {
deferred.resolve(response.data);
}, function(error) {
deferred.reject(error);
});
return deferred.promise;
};
function processFlightData(data, airports) {
self.flights = papa.parse(data, { header: true }).data;
var dests = self.flights.map(function(flight) { return flight.destination });
var destSet = new Set(dests);
destSet.forEach(function(dest) {
var airport = airports.find(function(airport) {
return airport.iata === dest
});
if (typeof airport !== 'undefined') {
self.airports.push(airport);
}
});
self.flights.forEach(function(flight) {
var origin = flight.origin;
var dest = flight.destination;
if (typeof self.routes[dest] === 'undefined') {
self.routes[dest] = [];
}
if (typeof self.routes[dest][origin] === 'undefined') {
self.routes[dest][origin] = {
date: flight.date,
delay: flight.delay,
distance: flight.distance
};
}
});
return self.flights;
};
function getAirports() {
return self.airports;
};
function getFlightsTo(destination) {
return self.routes[destination];
};
return self;
});
当我在控制台上登录ctrl.flightsTo。
它总是改变得很好。
但视图与空数组保持相同的状态。
【问题讨论】:
-
使用
$scope而不是var self = this; -
@azad 我已经使用
$scope而不是self。但它不起作用。 -
你是在
self.flightsTo = flightDataService.getFlightsTo(item.iata);这行之后直接调用$scope.apply()吗? -
我看到你正在使用 http 调用,这里的答案可能会帮助你 stackoverflow.com/a/15476728/5272567 可能需要在 http 调用之后直接执行
$scope.apply() -
@Matthias 我确实在
self.flightsTo = flightDataService.getFlightsTo(item.iata);之后打电话给$scope.$apply()但它会犯像$digest already in progress这样的错误
标签: javascript angularjs arrays