自定义指令在ng-if中第二次绑定不正确
Custom directive not binding correctly in ng-if second time around
我有一个自定义指令,它使用双向绑定到我的控制器(使用'=')。
<my-streetview
latitude="quickView.streetView.latitude"
longitude="quickView.streetView.longitude"
ng-if="quickView.activeTab === 'street'"
></my-streetview>
我使用ng-if是因为我不希望谷歌地图/街景被加载,直到它所在的标签被打开。麻烦的是,第一次它显示一切工作,但第二次ng-if是真的(当你点击一个不同的选项卡,然后回到选项卡),它似乎设置了长和晚未定义。
我知道以下内容:
A)如果我改变ng-hide为ng-show,它只是工作。每次你离开并返回标签页时,谷歌地图不会被破坏和创建,所以这是有道理的。我想,这和ng-if破坏错误的东西有关。
B)后期和长值实际上在父控制器中被更改,因为我在那里放置了一个$watch和一个console.log()来测试它。基本上,当ng-if在第一次创建街景fine时被设置为true时,第二次和随后的时间它要么无法从父控制器读取值,要么实际上将它们设置为未定义。
C)在第一次显示ng-if和随后的次数之间没有其他不同。我想不出还有什么别的代码可以发挥作用。
如有任何意见,我将不胜感激。
这是我的街景指令的完整代码。
angular.module('my.directives')
.constant('myStreetviewDefaults', {
latitude: 51.816102,
longitude: -0.811619
})
.directive('myStreetview', function ($timeout, myStreetviewDefaults) {
return {
restrict: 'EA',
scope: {
latitude: '=',
longitude: '='
},
link: function ($scope, $element, $attrs) {
$scope.latitude = angular.isDefined($scope.latitude) ? $scope.$eval($scope.latitude) : myStreetviewDefaults.latitude;
$scope.longitude = angular.isDefined($scope.longitude) ? $scope.$eval($scope.longitude) : myStreetviewDefaults.longitude;
// Create the panorama
var mapEl = $('<my-streetview-map></my-streetview-map>');
mapEl.addClass('my-streetview-map-container');
$element.append(mapEl);
var panorama = new google.maps.StreetViewPanorama(mapEl[0], {
position: {
lat: $scope.latitude,
lng: $scope.longitude
},
pov: {
heading: 34,
pitch: 10
}
});
// Watch latitude and longitude to reset the center
$scope.$watchGroup(['latitude','longitude'], function (newValues, oldValues, $scope) {
panorama.setPosition({
lat: $scope.latitude,
lng: $scope.longitude
});
});
// Hack to get street view drawing properly on second load
// https://github.com/allenhwkim/angularjs-google-maps/issues/59
$timeout(function(){
google.maps.event.trigger(panorama,'resize');
}, 100);
}
};
});
这是街景所在的Angular UI模态的控制器代码。
angular.module('app')
.controller('QuickViewCtrl', function ($rootScope, $scope, $log, $http, appConfig, $u, $modalInstance, modalSettings) {
'use strict';
var master = $scope.master;
var quickView = this;
$log.info('Quick View Opened', modalSettings);
this.close = function(){
$modalInstance.close();
}
///////////////////////////////////////////////////////////////
// Initialize Page
///////////////////////////////////////////////////////////////
var init = function () {
// Set the initial tab
quickView.activeTab = modalSettings.initialPanel;
// Set up the street view
quickView.streetView = {
latitude: modalSettings.property.latitude,
longitude: modalSettings.property.longitude
};
$scope.$watch('quickView.streetView', function(newValues, oldValues){
console.log("Test watching from controller", newValues);
}, true);
};
init();
});
这是模态窗口的模板....
<div class="quickView modal-inner modal--has-header modal--has-footer">
<!-- Header -->
<div class="modal-header">
<!-- Header removed for brevity -->
</div>
<div class="modal-main">
<!-- Tabs -->
<my-tabset
my-tabset-active-tab="quickView.activeTab"
>
<div my-tabset-tabs my-tabset-tabs--equal4>
<a href="#" my-tabset-tab my-tabset-tab-name="overview" is-active="true">
<div my-tabset-tab-text>Overview</div>
</a>
<a href="#" my-tabset-tab my-tabset-tab-name="gallery">
<div my-tabset-tab-text>Gallery</div>
</a>
<a href="#" my-tabset-tab my-tabset-tab-name="map">
<div my-tabset-tab-text>Map</div>
</a>
<a href="#" my-tabset-tab my-tabset-tab-name="street">
<div my-tabset-tab-text>Street View</div>
</a>
</div>
<div my-tabset-panels>
<!-- Overview Panel -->
<div my-tabset-panel my-tabset-tab-name="overview" is-active="true">
<div ng-if="quickView.activeTab === 'overview'">
<!-- Overview removed for brevity -->
</div>
</div>
<!-- Gallery Panel -->
<div my-tabset-panel my-tabset-tab-name="gallery">
<div ng-if="quickView.activeTab === 'gallery'">
<!-- Gallery removed for brevity -->
</div>
</div>
<!-- Map Panel -->
<div my-tabset-panel my-tabset-tab-name="map">
<ui-gmap-google-map
center='quickView.map.center'
zoom='quickView.map.zoom'
options="quickView.map.options"
control="quickView.mapControl"
ng-if="quickView.activeTab === 'map'"
>
<ui-gmap-marker
idKey="'quickViewMapMarker'"
coords='quickView.map.markerPosition'
>
</ui-gmap-marker>
</ui-gmap-google-map>
</div>
<!-- Street View Panel -->
<div my-tabset-panel my-tabset-tab-name="street">
<my-streetview
latitude="quickView.streetView.latitude"
longitude="quickView.streetView.longitude"
ng-if="quickView.activeTab === 'street'"
></my-streetview>
</div>
</div>
</my-tabset>
</div>
<!-- Footer -->
<div class="modal-footer">
Footer
</div>
</div>
违规行如下:
$scope.latitude = angular.isDefined($scope.latitude) ? $scope.$eval($scope.latitude) : myStreetviewDefaults.latitude;
$scope.longitude = angular.isDefined($scope.longitude) ? $scope.$eval($scope.longitude) : myStreetviewDefaults.longitude;
不清楚你为什么使用$scope.$eval($scope.latitude)
,但它可能源于对$scope.$eval
的误解。
$scope.$eval
取一个表达式,例如:"quickView.streetView.latitude"
,并根据调用$eval
的$scope
求值。
你用$scope.latitude
作为参数来调用它,这意味着求值的表达式类似于35.344542
——显然不是作用域上定义的东西——所以你得到了undefined
。
也许你打算使用$attrs.latitude
-这将给你"quickView.streetView.latitude"
表达式,但你需要在父范围上调用它,因为你的指令使用一个不知道quickView
(等…)是什么的隔离范围:
$scope.$parent.$eval($attrs.latitude)
但更重要的是,你甚至根本不需要这个$eval
,因为$scope.latitude
已经通过双向绑定自动获取了求值。下面的代码也同样有效:
- iOS鼠标中心绑定只工作一次
- 如何绑定提交每ng次点击
- KnockoutJS绑定每个文档不止一次
- 数据互绑定问题:转换器只运行一次,无法绑定元素的 ID
- 主干.js绑定到集合“添加”呈现视图两次
- ES6/React第二项绑定失败
- AngularJs一次绑定和布尔运算符的值顺序
- 绑定到同一函数的角度元素.避免对每个摘要进行多次调用
- 点击处理程序多次触发,解除绑定不起作用
- 绑定两次或更多次的事件 jquery
- 如何将两个 html 元素绑定在一起,当第一个元素被删除时,第二个元素也从 DOM 中删除
- 如何将一个事件绑定两次到 JavaScript 插件
- 如何将第二个函数绑定到 jQuery 验证提交处理程序
- 多次绑定 jStepper 到输入元素
- 我想防止第二次点击,直到使用绑定和取消绑定完成动画,但它不起作用
- 在JavaScript中,第一个绑定决定了谁“;这个“;是(绑定两次或第二次并不重要)
- 自定义指令在ng-if中第二次绑定不正确
- 当与ngIf指令组合时,一次绑定重新计算变量是否正确?-AngularJS
- KnockoutJS在第二次绑定后复制UI中的数据
- 在JavaScript中多次绑定事件监听器