Wiele dyrektyw [mypopup, myDraggable] z pytaniem o nowy / wyodrębniony zakres

Napisałem dyrektywę dla okien dialogowych (myPopup) i inną do przeciągania tego okna (myDraggable) , ale zawsze dostaję błąd:

Wiele dyrektyw [myPopup, myDraggable] z pytaniem o nowy / izolowany zakres

Oto Plunker: http://plnkr.co/edit/kMQ0hK5RnVw5xOBdDq5P?p=preview

Co mogę zrobić?

Kod 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);
            }
        }
    };
}]);
Author: Blazemonger, 2014-03-10

7 answers

From docs :

Przykładowe scenariusze wielu niezgodnych dyrektyw stosowanych do ten sam element zawiera:

Wiele dyrektyw żądających wyodrębnionego zakresu .

Wiele dyrektyw publikujących kontroler pod tą samą nazwą.

Wiele dyrektyw zadeklarowanych z opcją transclusion.

Wiele dyrektyw próbujących zdefiniować szablon lub templateURL.

Spróbuj usunąć izolat zakres dyrektywy myDraggable:

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

Zastąp scope.enabled na attrs.enabled:

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

I zmodyfikować szablon, aby powiązać atrybut enable:

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

DEMO

 57
Author: Khanh TO,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-10 15:24:56

Element DOM powoduje kolizję z próbowanymi zakresami izolacyjnymi. Dlatego zawsze powinieneś zadać sobie pytanie, czy potrzebny jest izolowany zakres.

Rozważ usunięcie zakresu izolowanego na myDraggable, interpolację wartości myDraggable (tak jak to zrobiłeś w przypadku isDraggable) i dostęp do atrybutu w funkcji link.

<div class="draggable" my-draggable="{{isDraggable}}">I am draggable {{isDraggable}}</div>
...

replace: false,

link: function (scope, elm, attrs) {
  var startX, startY, initialMouseX, initialMouseY,
      enabled = attrs.myDraggable === 'true';
  if (enabled === true) {

...

Zobacz swój zaktualizowany Plunker tutaj i zauważ zmianę w szablonie myPopup.

Jeśli chcesz zobaczyć myDraggable zmiany atrybutów następnie zaimplementuj coś w stylu:

attrs.$observe('myDraggable', function(iVal) {
  enabled = iVal === 'true';
  // AND/OR
  if (iVal === 'true') doSomething();
});

Zobacz Angular attribute Docs $ observe function

 22
Author: Stephen J Barker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-07 15:15:47

Mój błąd był podobny:

Błąd: [$compile: multidir] wiele dyrektyw [groups, groups] pytanie o nowy / izolowany Zakres na:

W moim przypadku miałem duplikat deklaracji

 .component('groups', new GroupsComponent()); 

W aplikacji.js / app.plik ts

I jednocześnie na samym komponencie

const groups = angular.module('groups', ['toaster'])
.component('groups', new GroupsComponent());

Usuwanie go z aplikacji.js / app.ts Naprawiono problem.

 6
Author: d689p,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-10 13:15:43

Wpadłem w podobną sytuację. Jeśli to nie psuje twojego układu i zdecydowanie musisz mieć izolowany zakres dla obu dyrektyw, Moja propozycja to usunięcie właściwości replace: true z definicji dyrektywy myPopup.

 4
Author: Mihai Popescu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-20 12:35:19

Jest sposób na obejście tego.

Nie wyizolujesz zakresu dyrektywy, zamiast niego utworzymy nowy izolowany zakres używając $nowa metoda. Ta metoda tworzy nowy zakres potomny, jeśli użyjesz true w pierwszym parametrze, utworzy on izolowany zakres:

Jeśli true, to Zakres nie dziedziczy prototypowo z zakresu nadrzędnego. Zakres jest odizolowany, ponieważ nie widzi właściwości parent >scope. Przy tworzeniu widżetów przydatne jest aby widżet nie odczytał przypadkowo stanu nadrzędnego.

Ale nie jest to problemem, ponieważ mamy dostęp do zakresu prywatnego za pomocą funkcji link dyrektywy, więc możliwe jest równoległe działanie z" nadrzędnym " i izolowanym zakresem w bardzo bliskie zachowanie dyrektywy z izolowanym zakresem.

Se przykład poniżej:

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.

        //(...)
        }

Rozwinąłem tę pracę do dyrektywy walidacji, która działa bardzo dobrze.

 3
Author: LeonanCarvalho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-26 14:36:50

Dodałem plik dyrektywy js dwa razy, gdy skompresowałem moją aplikację. To spowodowało błąd.

 1
Author: Gerfried,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-12 19:35:00

Pomiń scope: {enabled: '=myDraggable' } z Twojej "myDraggable"-dyrektywy, której nie potrzebujesz. Więc:

  return {
    restrict: 'A',
    replace: false,
    link: function (scope, elm, attrs) {
 0
Author: mhtsbt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-10 15:01:11