jac*_*cob 16 javascript html5 angularjs angular-ui
我正在使用AngularUI的uiMap指令来实例化谷歌地图.uiMap指令适用于硬编码数据({mapOptions}和[myMarkers]); 但是当我通过$http.get()(在AJAX调用完成之前指令触发)检索此数据时遇到了麻烦.
最初我在我的GoogleMaps控制器中执行GET ,但是当我意识到事情发生的时候,我把GET转移到了uiMap指令中.我有两个问题:
[myMarkers]
所以我的问题是,是否在应用程序的其他地方我可以在指令运行之前检索数据(并将其应用于范围)?
我读了$ q,这听起来像我想要的,但我不确定我是否可以在我的控制器中而不是在指令中做到(也不确定$q.defer.resolve()有什么不同$http.success()).
编辑我使用的大部分代码都是从AngularUI的doc中复制/粘贴,但这里有一个插件:http://plnkr.co/edit/t2Nq57
<!-- index.html -->
<div
id="map_container"
ng-controller="GoogleMaps">
<div ui-if="mapReady">
<div
ng-repeat="marker in markers"
ui-map-marker="markers[$index]"
ui-event="{'map-click':'openMarkerInfo(marker)'}"
></div>
<div
ui-map-info-window="myInfoWindow"
ng-include="'infobox.html'"
></div>
<div
id="map_canvas"
ui-map="myMap"
ui-options="mapOptions"
></div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
警告1 uiIf不能在指定控制器提供其条件的同一元素中(uiIf具有比ngController更高的优先级,因此在uiIf执行之前它的控制器不会被设置).
警告2请务必使用最新版本的uiIf(最新标签v0.3.2中提供的版本已过期).在某些情况下,旧的错误导致TypeError.
必须在AngularJS之前包含警告3 jQuery(在index.html中); 否则你会收到一个TypeError声明Object [object Object] has no method 'trigger'(或Object [object HTMLDivElement] has no method 'trigger'在Windows上).Chrome将允许您进入触发器功能,因为Chrome知道它,但Angular没有(并且Angular会抛出错误).
function GoogleMaps( $scope , $http )
{
var mapDefaults = {
center: new google.maps.LatLng(25,-90),//centres on Gulf of Mexico
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
$scope.mapOptions = {};
$scope.mapReady = false;
$scope.markers = [];
$http.get('map.json').then(function mapData(response) {
var map_data = response.data,
user_defaults = map_data.user.defaults; //{center: [lat,lng], zoom: 15}
$scope.mapOptions = {
"center": (typeof user_defaults.center !== 'undefined') ?
new google.maps.LatLng(user_defaults.center[0],user_defaults.center[1])
: mapDefaults.center,
"zoom": (typeof user_defaults.zoom !== 'undefined') ?
parseInt(user_defaults.zoom,10)
: mapDefaults.zoom,
"mapTypeId": mapDefaults.mapTypeId
};
//working on code to populate markers object
$scope.mapReady = true;
});
// straight from sample on http://angular-ui.github.com/#directives-map
$scope.addMarker = function($event) { … };
$scope.openMarkerInfo = function(marker) { … };
$scope.setMarkerPosition = function(marker, lat, lng) { … };
}//GoogleMaps{}
Run Code Online (Sandbox Code Playgroud)
缺点 uiMap目前不支持渲染制作者.我正在研究这个GitHub问题/评论中建议的替代版本的uiMapMarker .
解决此问题的方法: https
: //stackoverflow.com/a/14617167/758177
工作示例: http: //plnkr.co/edit/0CMdW3?p = preview
And*_*lin 31
您可以延迟执行ui-map直到加载数据.
HTML:
<div ui-if="loadingIsDone">
<div ui-map="myMap" ui-options="myOpts"></div>
</div>
Run Code Online (Sandbox Code Playgroud)
JS:
$http.get('/mapdata').then(function(response) {
$scope.myOpts = response.data;
$scope.loadingIsDone = true;
});
Run Code Online (Sandbox Code Playgroud)
通常,您可以做的是设置您的指令,启动负载并完成成功.我假设您要为指令的所有实例加载一个数据.所以这里有一些伪代码,你可能想要攻击它:
app.directive('myDelayedDirective', ['$http', '$q', function($http, $q) {
//store the data so you don't load it twice.
var directiveData,
//declare a variable for you promise.
dataPromise;
//set up a promise that will be used to load the data
function loadData(){
//if we already have a promise, just return that
//so it doesn't run twice.
if(dataPromise) {
return dataPromise;
}
var deferred = $q.defer();
dataPromise = deferred.promise;
if(directiveData) {
//if we already have data, return that.
deferred.resolve(directiveData);
}else{
$http.get('/Load/Some/Data'))
.success(function(data) {
directiveData = data;
deferred.resolve(directiveData);
})
.error(function() {
deferred.reject('Failed to load data');
});
}
return dataPromise;
}
return {
restrict: 'E',
template: '<div>' +
'<span ng-hide="data">Loading...</span>' +
'<div ng-show="data">{{data}}</div>' +
'</div>',
link: function(scope, elem, attr) {
//load the data, or check if it's loaded and apply it.
loadData().then(function(data) {
//success! set your scope values and
// do whatever dom/plugin stuff you need to do here.
// an $apply() may be necessary in some cases.
scope.data = data;
}, function() {
//failure! update something to show failure.
// again, $apply() may be necessary.
scope.data = 'ERROR: failed to load data.';
})
}
}
}]);
Run Code Online (Sandbox Code Playgroud)
无论如何,我希望有所帮助.