Angularjs 多个指令[myPopup,MyDragable]请求新的/隔离的作用域
我写了一个对话框指令(myPopup)和另一个用于拖动此对话框的指令(MyDragable),但我总是得到错误: 多个指令[myPopup,MyDragable]请求新的/隔离的作用域 这是一个扑克牌: 我能做什么 JS代码:Angularjs 多个指令[myPopup,MyDragable]请求新的/隔离的作用域,angularjs,scope,angularjs-directive,Angularjs,Scope,Angularjs Directive,我写了一个对话框指令(myPopup)和另一个用于拖动此对话框的指令(MyDragable),但我总是得到错误: 多个指令[myPopup,MyDragable]请求新的/隔离的作用域 这是一个扑克牌: 我能做什么 JS代码: var app = angular.module('myApp', []); function myController($scope) { $scope.isDraggable = true; } app.directive('myPopup', [
var app = angular.module('myApp', []);
function myController($scope) {
$scope.isDraggable = true;
}
app.directive('myPopup', [
function () {
"use strict";
return {
restrict: 'E',
replace: true,
transclude: true,
template: '<div my-draggable="draggable"class="dialog"><div class="title">{{title}}</div><div class="content" ng-transclude></div></div>',
scope: {
title: '@?dialogTitle',
draggable: '@?isDraggable',
width: '@?width',
height: '@?height',
},
controller: function ($scope) {
// Some code
},
link: function (scope, element, attr) {
if (scope.width) {
element.css('width', scope.width);
}
if (scope.height) {
element.css('height', scope.height);
}
}
};
}
]);
app.directive('myDraggable', ['$document',
function ($document) {
return {
restrict: 'A',
replace: false,
scope: { enabled: '=myDraggable' },
link: function (scope, elm, attrs) {
var startX, startY, initialMouseX, initialMouseY;
if (scope.enabled === true) {
elm.bind('mousedown', function ($event) {
startX = elm.prop('offsetLeft');
startY = elm.prop('offsetTop');
initialMouseX = $event.clientX;
initialMouseY = $event.clientY;
$document.bind('mousemove', mousemove);
$document.bind('mouseup', mouseup);
$event.preventDefault();
});
}
function getMaxPos() {
var computetStyle = getComputedStyle(elm[0], null);
var tx, ty;
var transformOrigin =
computetStyle.transformOrigin ||
computetStyle.webkitTransformOrigin ||
computetStyle.MozTransformOrigin ||
computetStyle.msTransformOrigin ||
computetStyle.OTransformOrigin;
tx = Math.ceil(parseFloat(transformOrigin));
ty = Math.ceil(parseFloat(transformOrigin.split(" ")[1]));
return {
max: {
x: tx + window.innerWidth - elm.prop('offsetWidth'),
y: ty + window.innerHeight - elm.prop('offsetHeight')
},
min: {
x: tx,
y: ty
}
};
}
function mousemove($event) {
var x = startX + $event.clientX - initialMouseX;
var y = startY + $event.clientY - initialMouseY;
var limit = getMaxPos();
x = (x < limit.max.x) ? ((x > limit.min.x) ? x : limit.min.x) : limit.max.x;
y = (y < limit.max.y) ? ((y > limit.min.y) ? y : limit.min.y) : limit.max.y;
elm.css({
top: y + 'px',
left: x + 'px'
});
$event.preventDefault();
}
function mouseup() {
$document.unbind('mousemove', mousemove);
$document.unbind('mouseup', mouseup);
}
}
};
}]);
var-app=angular.module('myApp',[]);
函数myController($scope){
$scope.isDraggable=true;
}
应用程序指令('myPopup'[
函数(){
“严格使用”;
返回{
限制:'E',
替换:正确,
是的,
模板:“{{title}}”,
范围:{
标题:“@?dialogTitle”,
可拖动:“@?IsDragable”,
宽度:“@?宽度”,
高度:“@?高度”,
},
控制器:功能($scope){
//一些代码
},
链接:功能(范围、元素、属性){
if(范围宽度){
css('width',scope.width);
}
if(范围高度){
css('height',scope.height);
}
}
};
}
]);
应用程序指令('MyDragable',['$document',
职能(文件){
返回{
限制:“A”,
替换:false,
作用域:{enabled:'=myDraggable'},
链接:功能(范围、elm、属性){
变量startX、startY、initialMouseX、initialMouseY;
如果(scope.enabled==true){
elm.bind('mousedown',函数($event){
startX=elm.prop('offsetLeft');
startY=elm.prop(“offsetTop”);
initialMouseX=$event.clientX;
initialMouseY=$event.clientY;
$document.bind('mousemove',mousemove);
$document.bind('mouseup',mouseup);
$event.preventDefault();
});
}
函数getMaxPos(){
var computetStyle=getComputedStyle(elm[0],null);
var-tx,ty;
变量转换原点=
computetStyle.transformOrigin||
computetStyle.webkitTransformOrigin||
computetStyle.MozTransformOrigin||
computetStyle.msTransformOrigin||
computetStyle.OTransformOrigin;
tx=Math.ceil(parseFloat(transformOrigin));
ty=Math.ceil(parseFloat(transformOrigin.split)(“”[1]);
返回{
最大值:{
x:tx+window.innerWidth-elm.prop('offsetWidth'),
y:ty+window.innerHeight-elm.prop('offsetHeight'))
},
最小值:{
x:tx,
y:泰
}
};
}
函数mousemove($event){
var x=startX+$event.clientX-initialMouseX;
变量y=startY+$event.clientY-initialMouseY;
var limit=getMaxPos();
x=(xlimit.min.x)?x:limit.min.x):limit.max.x;
y=(ylimit.min.y)?y:limit.min.y):limit.max.y;
elm.css({
顶部:y+‘px’,
左:x+‘px’
});
$event.preventDefault();
}
函数mouseup(){
$document.unbind('mousemove',mousemove);
$document.unbind('mouseup',mouseup);
}
}
};
}]);
来自:
多个不兼容指令应用于
同一要素包括:
请求隔离作用域的多个指令
以相同名称发布控制器的多个指令
使用转换选项声明的多个指令
试图定义模板或templateURL的多个指令
尝试删除myDraggable
指令上的隔离作用域:
app.directive('myDraggable', ['$document',
function ($document) {
return {
restrict: 'A',
replace: false,
scope: { enabled: '=myDraggable' }, //remove this line
将启用的范围替换为启用的属性:
if (attrs.enabled == "true") {
并修改模板以绑定“启用”属性:
<div my-draggable="draggable" enabled="{{draggable}}"
从“myDraggable”指令中省略作用域:{enabled:'=myDraggable'},您不需要它。因此:
return {
restrict: 'A',
replace: false,
link: function (scope, elm, attrs) {
DOM元素正在创建与您尝试的隔离作用域的冲突。因此,您应该经常问自己是否需要隔离范围
考虑删除myDraggable
上的隔离作用域,插入myDraggable值(就像您对isDraggable所做的那样),并访问链接
函数中的属性
<div class="draggable" my-draggable="{{isDraggable}}">I am draggable {{isDraggable}}</div>
查看更新的Plunker并注意myPopup模板中的更改
如果要查看MyDragable属性的更改,请执行以下操作:
attrs.$observe('myDraggable',函数(iVal){
enabled=iVal==‘true’;
//和/或
如果(iVal=='true')doSomething();
});
请参阅$observe函数我的错误与此类似:
错误:[$compile:multidir]多个指令[groups,groups]要求在以下位置上创建新的/隔离的作用域:
在我的情况下,我有重复的声明
.component('groups', new GroupsComponent());
在app.js/app.ts文件中
同时在组件本身上
const groups = angular.module('groups', ['toaster'])
.component('groups', new GroupsComponent());
从app.js/app.ts中删除它修复了这个问题。我遇到了类似的情况。如果它不会打乱您的布局,并且您肯定需要在两个指令上都有一个独立的作用域,我的建议是从myPopup指令定义中删除属性replace:true
。有一种解决方法。
您不会隔离指令的作用域,相反,我们将使用创建一个新的隔离作用域。如果在第1段中使用true,则此方法将创建一个新的子范围
app.directive('myDraggable', ['$document',
function ($document) {
return {
restrict: 'A',
replace: false,
scope: false,
//scope: { enabled: '=myDraggable', oneWayAttr: "@" }, //Just for reference I introduced a new
link: function(parentScope, elem, attr) {
var scope = parentScope.$new(true); //Simulated isolation.
scope.oneWayAttr = attr.oneWayAttr; //one-way binding @
scope.myDraggable = parentScope.$parent.$eval(attr.myDraggable);
scope.watchmyDraggable = function () {
return scope.myDraggable = parentScope.$parent.$eval(attr.myDraggable); //parent -> isolatedscope
};
scope.$watch(scope.watchmyDraggable, function(newValue, oldValue) {
//(...)
});
parentScope.innerScope = scope; //If you need view access, you must create a kind of symbolic link to it.
//(...)
}