Angularjs 多个指令[myPopup,MyDragable]请求新的/隔离的作用域

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', [

我写了一个对话框指令(myPopup)和另一个用于拖动此对话框的指令(MyDragable),但我总是得到错误:

多个指令[myPopup,MyDragable]请求新的/隔离的作用域

这是一个扑克牌:

我能做什么

JS代码:

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.

        //(...)
        }