在 AngularJS 中使用指令的多个子 HTML 元素出现问题
Issue with multiple child HTML elements using Directives in AngularJS
我正在使用一个模板来创建一个弹出菜单,如果有新菜单,它会显示警报并且它一直有效。但是我想添加手动警报,这就是为什么我想添加一个输入文本但是天啊,我不能在输入字段上写,我什至不知道为什么。输入字段有点禁用!!!
我的指令是这样的:
$scope.tb = { x: 0, y: 0 };
module.directive('myDraggable', function ($document, $interval) {
return {
restrict: 'EA',
replace: true,
//scope : true,
scope: { menu: '=drSrc'},
link: function (scope, element, attr) {
var startX = 0, startY = 0, x = scope.menu.x || 0, y = scope.menu.y || 0, positionX = [], positionY = [], time = [], width, height, moveInterval;
element.draggable({
position: 'relative',
cursor: 'pointer',
top: y + 'px',
left: x + 'px'
});
element.on('mousedown', function (event) {
// Prevent default dragging of selected content
event.preventDefault();
startX = event.pageX - x;
startY = event.pageY - y;
$document.on('mousemove', mousemove);
$document.on('mouseup', mouseup);
$interval.cancel(moveInterval);
});
function mousemove(event) {
y = event.pageY - startY;
x = event.pageX - startX;
//calculate the borders of the document
width = $(document).width() - 350;
height = $(document).height() - 150;
positionX.push(x);
positionY.push(y);
time.push(Date.now());
}
}
}
});
我试图使范围为真,但我遇到了 2 个问题:
我不能再移动我的弹出菜单(是的,我的弹出菜单是可拖动的)
而且输入文本不显示我正在输入的文本。
这是我的缓存模板:
$templateCache.put('control.tpl.html', '<div class="container" my-draggable dr-src="tb"><div><div class="col-sm-1 col-md-1 sidebar"><div class="list-group" ><span href="#" class="list-group-item active" >Manage<input type="text" class="pull-right" placeholder="Type..." /></span><div ng-repeat="Alert in Alerts"><a href="#" ng-click="showLocation(Alert.id)" class="list-group-item" >Alert {{Alert.id}}</span><img src="../images/alert_icon_manage.png" class="pull-right"/> </a></div><span href="#" class="list-group-item active"></span></div></div></div></div>');
我是 AngularJS 和指令的新手,我不知道如何解决这个问题,但我认为这是作用域的问题!!
谢谢。
更新:
如果我删除 scope:{menu:"=drSrc"} 那行得通,我可以输入我想要的内容,但问题是我的元素不再可拖动。
我认为这与范围有关。有人可以帮忙吗?
scope: true
指示您的指令应继承其父级的作用域,但 scope: {menu: '=drSrc'}
创建一个独立的作用域,这会删除您的模板对 Alerts
的访问权限。当您删除 scope: {menu: '=drSrc'}
时,menu
不再存在,因此 scope.menu.x
失败并且您的元素不再可拖动。
最简单的解决方法是使用 scope: true
和引用 scope.drSrc.x
等,而不是 scope.menu.x
。使用 scope: true
,您可以访问父级的范围,包括 drSrc
和您的模板正在使用的 Alerts
数据。
这些文章有助于理解指令和作用域:
- Angular's directive docs
- Understanding Scopes
- What is the difference between '@' and '=' in directive scope
我目前正在从事一个严重依赖模态对话框的项目。每个都有自己的目的和动态内容。
这是我一直在使用的系统:
index.html
<!doctype html>
<html ng-app="myApp" ng-controller="MainCtrl">
<head>
<title>Dialogs</title>
<link rel="stylesheet" href="app.css">
</head>
<body>
<button ng-click="openDialog()">Open Dialog</button>
<modal-dialog show="showMe" dialog-controller="WelcomeDialogCtrl" context="welcome"></modal-dialog>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js
var app = angular.module('myApp', []);
// The main controller, which will handle index.html
app.controller('MainCtrl', ['$scope', function($scope) {
$scope.showMe = false;
$scope.openDialog = function(){
$scope.showMe = true; // Show the 'welcome' dialog
};
}]);
// The modal dialog directive
app.directive('modalDialog', [function() {
return {
controller: '@', // Bind a controller
name: 'dialogController', // Bind the controller to this attribute name
restrict: 'E',
scope: {
show: '='
},
link: function(scope, element, attrs) {
// Close this dialog (actually ng-hides it)
scope.closeDialog = function() {
scope.show = false;
};
},
templateUrl: function(element, attrs){
// I prefer to load my dialog templates from a separate folder to keep my project tidy
return 'dialogs/' + attrs.context + '.html';
}
};
}]);
// The 'welcome' dialog has its own controller with its own scope
app.controller('WelcomeDialogCtrl', ['$scope', function($scope){
// This can be called by the template that resides within the directive
$scope.exampleFunction = function(text){
console.log('Example function says: ' + text);
};
}]);
welcome.html
<div class="dialog" ng-show="show">
<div class="dialog-overlay"></div>
<div class="dialog-box">
Welcome, be sure to check out this blazin' dialog.
<button ng-click="exampleFunction('Hi!')">Say Hi!</button>
<button ng-click="closeDialog()">Close</button>
</div>
</div>
app.css
body{
background: #eee;
margin: 80px;
}
/*
* Just some fancy schmuck
*/
button{
border-radius: 5px;
background: #272;
color: #fff;
padding: 5px 12px;
border: 0;
}
/*
* The grey, transparent curtain.
*/
.dialog-overlay {
width: 100%;
height: 100%;
position: absolute;
background: #111;
opacity: 0.2;
top: 0;
left: 0;
z-index: 100;
}
/*
* The dialog itself. Horribly centered.
*/
.dialog-box{
background: #fff;
border-radius: 5px;
padding: 10px 20px;
position: absolute;
width: 600px;
height: 300px;
top: 50%;
left: 50%;
margin-left: -300px;
z-index: 110;
}
我也用同样的代码做了一个Plunker
我正在使用一个模板来创建一个弹出菜单,如果有新菜单,它会显示警报并且它一直有效。但是我想添加手动警报,这就是为什么我想添加一个输入文本但是天啊,我不能在输入字段上写,我什至不知道为什么。输入字段有点禁用!!!
我的指令是这样的:
$scope.tb = { x: 0, y: 0 };
module.directive('myDraggable', function ($document, $interval) {
return {
restrict: 'EA',
replace: true,
//scope : true,
scope: { menu: '=drSrc'},
link: function (scope, element, attr) {
var startX = 0, startY = 0, x = scope.menu.x || 0, y = scope.menu.y || 0, positionX = [], positionY = [], time = [], width, height, moveInterval;
element.draggable({
position: 'relative',
cursor: 'pointer',
top: y + 'px',
left: x + 'px'
});
element.on('mousedown', function (event) {
// Prevent default dragging of selected content
event.preventDefault();
startX = event.pageX - x;
startY = event.pageY - y;
$document.on('mousemove', mousemove);
$document.on('mouseup', mouseup);
$interval.cancel(moveInterval);
});
function mousemove(event) {
y = event.pageY - startY;
x = event.pageX - startX;
//calculate the borders of the document
width = $(document).width() - 350;
height = $(document).height() - 150;
positionX.push(x);
positionY.push(y);
time.push(Date.now());
}
}
}
});
我试图使范围为真,但我遇到了 2 个问题: 我不能再移动我的弹出菜单(是的,我的弹出菜单是可拖动的) 而且输入文本不显示我正在输入的文本。
这是我的缓存模板:
$templateCache.put('control.tpl.html', '<div class="container" my-draggable dr-src="tb"><div><div class="col-sm-1 col-md-1 sidebar"><div class="list-group" ><span href="#" class="list-group-item active" >Manage<input type="text" class="pull-right" placeholder="Type..." /></span><div ng-repeat="Alert in Alerts"><a href="#" ng-click="showLocation(Alert.id)" class="list-group-item" >Alert {{Alert.id}}</span><img src="../images/alert_icon_manage.png" class="pull-right"/> </a></div><span href="#" class="list-group-item active"></span></div></div></div></div>');
我是 AngularJS 和指令的新手,我不知道如何解决这个问题,但我认为这是作用域的问题!! 谢谢。
更新:
如果我删除 scope:{menu:"=drSrc"} 那行得通,我可以输入我想要的内容,但问题是我的元素不再可拖动。 我认为这与范围有关。有人可以帮忙吗?
scope: true
指示您的指令应继承其父级的作用域,但 scope: {menu: '=drSrc'}
创建一个独立的作用域,这会删除您的模板对 Alerts
的访问权限。当您删除 scope: {menu: '=drSrc'}
时,menu
不再存在,因此 scope.menu.x
失败并且您的元素不再可拖动。
最简单的解决方法是使用 scope: true
和引用 scope.drSrc.x
等,而不是 scope.menu.x
。使用 scope: true
,您可以访问父级的范围,包括 drSrc
和您的模板正在使用的 Alerts
数据。
这些文章有助于理解指令和作用域:
- Angular's directive docs
- Understanding Scopes
- What is the difference between '@' and '=' in directive scope
我目前正在从事一个严重依赖模态对话框的项目。每个都有自己的目的和动态内容。
这是我一直在使用的系统:
index.html
<!doctype html>
<html ng-app="myApp" ng-controller="MainCtrl">
<head>
<title>Dialogs</title>
<link rel="stylesheet" href="app.css">
</head>
<body>
<button ng-click="openDialog()">Open Dialog</button>
<modal-dialog show="showMe" dialog-controller="WelcomeDialogCtrl" context="welcome"></modal-dialog>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js
var app = angular.module('myApp', []);
// The main controller, which will handle index.html
app.controller('MainCtrl', ['$scope', function($scope) {
$scope.showMe = false;
$scope.openDialog = function(){
$scope.showMe = true; // Show the 'welcome' dialog
};
}]);
// The modal dialog directive
app.directive('modalDialog', [function() {
return {
controller: '@', // Bind a controller
name: 'dialogController', // Bind the controller to this attribute name
restrict: 'E',
scope: {
show: '='
},
link: function(scope, element, attrs) {
// Close this dialog (actually ng-hides it)
scope.closeDialog = function() {
scope.show = false;
};
},
templateUrl: function(element, attrs){
// I prefer to load my dialog templates from a separate folder to keep my project tidy
return 'dialogs/' + attrs.context + '.html';
}
};
}]);
// The 'welcome' dialog has its own controller with its own scope
app.controller('WelcomeDialogCtrl', ['$scope', function($scope){
// This can be called by the template that resides within the directive
$scope.exampleFunction = function(text){
console.log('Example function says: ' + text);
};
}]);
welcome.html
<div class="dialog" ng-show="show">
<div class="dialog-overlay"></div>
<div class="dialog-box">
Welcome, be sure to check out this blazin' dialog.
<button ng-click="exampleFunction('Hi!')">Say Hi!</button>
<button ng-click="closeDialog()">Close</button>
</div>
</div>
app.css
body{
background: #eee;
margin: 80px;
}
/*
* Just some fancy schmuck
*/
button{
border-radius: 5px;
background: #272;
color: #fff;
padding: 5px 12px;
border: 0;
}
/*
* The grey, transparent curtain.
*/
.dialog-overlay {
width: 100%;
height: 100%;
position: absolute;
background: #111;
opacity: 0.2;
top: 0;
left: 0;
z-index: 100;
}
/*
* The dialog itself. Horribly centered.
*/
.dialog-box{
background: #fff;
border-radius: 5px;
padding: 10px 20px;
position: absolute;
width: 600px;
height: 300px;
top: 50%;
left: 50%;
margin-left: -300px;
z-index: 110;
}
我也用同样的代码做了一个Plunker