多个指令 [myPopup, myDraggable] 要求新的/隔离的范围 [英] Multiple directives [myPopup, myDraggable] asking for new/isolated scope

查看:24
本文介绍了多个指令 [myPopup, myDraggable] 要求新的/隔离的范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<块引用>

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

这是一个 Plunker:http://plnkr.co/edit/kMQ0hK5RnVw5xOBdDq5P?p=preview

我能做什么?

JS代码:

var app = angular.module('myApp', []);功能 myController($scope) {$scope.isDraggable = true;}app.directive('myPopup', [功能 () {严格使用";返回 {限制:'E',替换:真的,转置:真实,模板:'<div my-draggable="draggable"class="dialog"><div class="title">{{title}}</div><div class="content" ng-transclude></div></div>',范围: {title: '@?dialogTitle',可拖动: '@?isDraggable',宽度: '@?width',高度: '@?height',},控制器:函数($scope){//一些代码},链接:函数(范围、元素、属性){如果(范围.宽度){element.css('width', scope.width);}如果(范围.高度){element.css('height', scope.height);}}};}]);app.directive('myDraggable', ['$document',功能($文档){返回 {限制:'A',替换:假,范围:{启用:'=myDraggable'},链接:功能(范围,榆树,属性){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();});}函数 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]));返回 {最大限度: {x: tx + window.innerWidth - elm.prop('offsetWidth'),y: ty + window.innerHeight - elm.prop('offsetHeight')},分钟:{x: tx,y: ty}};}功能鼠标移动($事件){var x = startX + $event.clientX - initialMouseX;var y = startY + $event.clientY - initialMouseY;var limit = getMaxPos();x = (x  limit.min.x) ? x : limit.min.x) : limit.max.x;y = (y  limit.min.y) ? y : limit.min.y) : limit.max.y;榆树.css({顶部:y + 'px',左:x + 'px'});$event.preventDefault();}功能鼠标向上(){$document.unbind('mousemove', mousemove);$document.unbind('mouseup', mouseup);}}};}]);

解决方案

来自 文档:

<块引用>

应用于多个不兼容指令的示例场景相同的元素包括:

请求隔离范围的多个指令.

多个指令以相同的名称发布控制器.

使用嵌入选项声明的多个指令.

多个指令试图定义模板或模板URL.

尝试移除 myDraggable 指令上的隔离作用域:

app.directive('myDraggable', ['$document',功能($文档){返回 {限制:'A',替换:假,scope: { enabled: '=myDraggable' },//删除这一行

scope.enabled 替换为 attrs.enabled:

if (attrs.enabled == "true") {

并修改您的模板以绑定启用属性:

演示

I wrote a directive for dialogs (myPopup) and another one for dragging this dialog (myDraggable), but I allways get the error:

Multiple directives [myPopup, myDraggable] asking for new/isolated scope

Here is a Plunker: http://plnkr.co/edit/kMQ0hK5RnVw5xOBdDq5P?p=preview

What can I do?

JS code:

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);
            }
        }
    };
}]);

解决方案

From docs:

Example scenarios of multiple incompatible directives applied to the same element include:

Multiple directives requesting isolated scope.

Multiple directives publishing a controller under the same name.

Multiple directives declared with the transclusion option.

Multiple directives attempting to define a template or templateURL.

Try removing isolate scope on myDraggable's directive:

app.directive('myDraggable', ['$document',
    function ($document) {
    return {
        restrict: 'A',
        replace: false,
        scope: { enabled: '=myDraggable' }, //remove this line

Replace scope.enabled with attrs.enabled:

if (attrs.enabled == "true") {

And modify your template to bind the enable attribute:

<div my-draggable="draggable" enabled="{{draggable}}"

DEMO

这篇关于多个指令 [myPopup, myDraggable] 要求新的/隔离的范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆