Javascript AngularJS操纵父对象';指令中的DOM
我是新来安格拉斯的。我搜索了一些关于如何在指令中操作DOM的页面,但大多数页面都是在操作指令本身的DOM。我的问题是在指令之外操作DOM 在我的项目中有一个谷歌地图,地图上有一些显示事件的标记。我想做的是,当单击标记时,应用程序应该在一个滑动条中显示事件的详细信息。根据下面的代码,当我在指令中单击触发updateMarkers()的标记时,需要更改HTML中{{detail}}的值。我现在所做的是尝试使用“=”为其控制器范围中的值提供指令访问权限,但这种方式不起作用。所以如果你知道的话,请提供一些帮助,谢谢 HTML: 指令:Javascript AngularJS操纵父对象';指令中的DOM,javascript,jquery,angularjs,google-maps,dom,Javascript,Jquery,Angularjs,Google Maps,Dom,我是新来安格拉斯的。我搜索了一些关于如何在指令中操作DOM的页面,但大多数页面都是在操作指令本身的DOM。我的问题是在指令之外操作DOM 在我的项目中有一个谷歌地图,地图上有一些显示事件的标记。我想做的是,当单击标记时,应用程序应该在一个滑动条中显示事件的详细信息。根据下面的代码,当我在指令中单击触发updateMarkers()的标记时,需要更改HTML中{{detail}}的值。我现在所做的是尝试使用“=”为其控制器范围中的值提供指令访问权限,但这种方式不起作用。所以如果你知道的话,请提供一
app.directive("appMap", ['$http', function ($http) {
return {
restrict: "E",
replace: true,
template: "<div></div>",
scope: {
center: "=", // Center point on the map (e.g. <code>{ latitude: 10, longitude: 10 }</code>).
markers: "=", // Array of map markers (e.g. <code>[{ lat: 10, lon: 10, name: "hello" }]</code>).
details: "=", //used for resend a REST api and store data in here
width: "@", // Map width in pixels.
height: "@", // Map height in pixels.
zoom: "@", // Zoom level (one is totally zoomed out, 25 is very much zoomed in).
mapTypeId: "@", // Type of tile to show on the map (roadmap, satellite, hybrid, terrain).
panControl: "@", // Whether to show a pan control on the map.
zoomControl: "@", // Whether to show a zoom control on the map.
scaleControl: "@", // Whether to show scale control on the map.
onInit: "&",
showDetail: "&"
},
link: function (scope, element, attrs) {
//some code.....
function updateMarkers() {
if (map && scope.markers.length > 0) {
window.alert("get me");
// clear old markers
if (currentMarkers != null) {
for (var i = 0; i < currentMarkers.length; i++) {
currentMarkers.setMap(null);
window.alert("get here1*****");
}
}
// create new markers
currentMarkers = [];
var markers = scope.markers;
function makeHappen(thi){
return function(){
scope.details = thi;
window.alert("***" + "in directive " + thi);
}
}
for (var i = 1; i < markers.length-1; i++) {
var m = markers[i];
if(m.venue == null || m.venue.lat == 0.0)
continue;
var loc = new google.maps.LatLng(m.venue.lat, m.venue.lon);
var eventName = m.description;
var mm = new google.maps.Marker({ position: loc, map: map, title: m.name, id: m.id, count: i});
mm.addListener('click', makeHappen(eventName), false);
currentMarkers.push(mm);
}
}
}
我认为这是一个与本文报道的问题类似的问题: 希望有帮助 使用
符号正确启用双向数据绑定<代码>详细信息是控制器中的基本类型。虽然指令中的隔离作用域可以访问详细信息
,但当您在makeoccure
函数中将某些内容分配给详细信息
时,它会在隔离作用域中创建一个新的详细信息
在这种情况下,不要在控制器中使用原语类型$scope.details
,而是将其设置为对象,例如:$scope.details={msg:'something'}
。在模板中打印它,即:{{details.msg}。在隔离范围的makeocound
函数中,将details
更改为details.msg
。
更新
对不起,我弄错了。看起来,您不需要将范围。详细信息从字符串更改为对象。下面的更改足以让它工作
function makeHappen(thi){
return function(){
scope.$apply(function() {
scope.details = thi;
})
}
}
对于隔离作用域,只要指令作用域中的共享变量(与指令作用域共享的控制器作用域变量)发生更改,控制器中的变量也会更新。它是原语还是对象并不重要,因为指令作用域和控制器作用域之间没有原型继承。但是,如果指令的scope属性为true(scope:true
),而不是隔离作用域,则scope.details必须是一个对象才能查看控制器作用域中更改的值(我前面解释过)
所需的唯一更改是将scope.details=thi
包装在范围内。$apply(function(){//code})
或在makeoccurrent函数末尾调用scope.$apply()
因此,问题是,为什么需要调用scope.$apply()
或将某些代码放入scope.$apply(function(){//code})
?原因是:
$apply()用于从外部以角度执行表达式
角度框架。(例如,从浏览器DOM事件,
setTimeout、XHR或第三方库)
在您的例子中,您附加了一个事件侦听器mm.addListener('click',makeOccess(eventName),false)代码>。每当单击标记时,就会调用makeoccure
函数。它发生在角度上下文之外。Angular不知道范围。详细信息值已更改。因此,scope.details
的观察者不会被调用,因此,您不会看到任何更新。还有,解决方案scope.$apply()
。无论何时调用scope.$apply()
,它都会在内部调用scope.$digest()
,这实际上会更新任何绑定或监视程序
那么,什么时候需要调用范围。$apply()
?在幕后,Angular将您在Angular上下文中编写的几乎所有代码包装在$apply()中。类似于ng click
或$timeout
或$http
回调的事件被包装在范围内。$apply()
因此不需要显式调用它。如果调用$apply yourself,则会出现错误
有关$apply的更多信息,请访问以下链接:
$rootScope.Scope#$apply
为了让您更好地理解指令中的不同范围场景,以及为什么在某些情况下需要$apply
,我做了一个简单的说明。请看一看这张照片。
感谢您的回复,您给我的链接是关于在控制器at指令中使用属性的,但我想做的是更改控制器at指令中属性的值。有没有其他的链接你可能知道,谢谢我实际上尝试过的方法在链接之前。虽然我可以在指令中访问控制器的属性,但不能更改其值。就像我没有使用$apply()一样。是细节还是细节?我可以看到它们都被使用了。详细信息,对不起。我不知道为什么这里的编辑是错误的。但在我的代码中,HTML和JS部分都称为“细节”。我已经在这里改了。要更改由details
属性定义的父范围变量的值,只需将其设置为scope.details='newvalue'代码>。嗨,谢谢你的帮助。将其作为一个对象工作。换言之,我在makeoccure函数中更改了details.msg之后添加了scope.$apply()。
app.directive("appMap", ['$http', function ($http) {
return {
restrict: "E",
replace: true,
template: "<div></div>",
scope: {
center: "=", // Center point on the map (e.g. <code>{ latitude: 10, longitude: 10 }</code>).
markers: "=", // Array of map markers (e.g. <code>[{ lat: 10, lon: 10, name: "hello" }]</code>).
details: "=", //used for resend a REST api and store data in here
width: "@", // Map width in pixels.
height: "@", // Map height in pixels.
zoom: "@", // Zoom level (one is totally zoomed out, 25 is very much zoomed in).
mapTypeId: "@", // Type of tile to show on the map (roadmap, satellite, hybrid, terrain).
panControl: "@", // Whether to show a pan control on the map.
zoomControl: "@", // Whether to show a zoom control on the map.
scaleControl: "@", // Whether to show scale control on the map.
onInit: "&",
showDetail: "&"
},
link: function (scope, element, attrs) {
//some code.....
function updateMarkers() {
if (map && scope.markers.length > 0) {
window.alert("get me");
// clear old markers
if (currentMarkers != null) {
for (var i = 0; i < currentMarkers.length; i++) {
currentMarkers.setMap(null);
window.alert("get here1*****");
}
}
// create new markers
currentMarkers = [];
var markers = scope.markers;
function makeHappen(thi){
return function(){
scope.details = thi;
window.alert("***" + "in directive " + thi);
}
}
for (var i = 1; i < markers.length-1; i++) {
var m = markers[i];
if(m.venue == null || m.venue.lat == 0.0)
continue;
var loc = new google.maps.LatLng(m.venue.lat, m.venue.lon);
var eventName = m.description;
var mm = new google.maps.Marker({ position: loc, map: map, title: m.name, id: m.id, count: i});
mm.addListener('click', makeHappen(eventName), false);
currentMarkers.push(mm);
}
}
}
function makeHappen(thi){
return function(){
scope.$apply(function() {
scope.details = thi;
})
}
}