0

OK, I am trying to put together a KineticJS app in Angular as soon as possible. Been wrestling with a simple issue. There is an example for setting up a KineticJS draggable shape in AngularJS here: http://blogs.microsoft.co.il/choroshin/2014/01/07/angularjs-html5-canvas-drag-and-drop-directive-using-kineticjs/. In this example code, which I copied exactly to my own server, the following error appears:

Error: [$compile:nonassign] Expression 'false' used with directive 'draggableCanvas' is non-assignable!

This same error occurs in the original fiddle as well, so I know the problem is in the original code. I am just not sure what the problem is, exactly. It seems that the HTML element is not correct and it's probably an easy thing to solve. I just don't see it. Thoughts? Here's a link to the fiddle: http://jsfiddle.net/choroshin/a68F5/light/

Here is the HTML code:

 <div ng-app="myApp">
  <div>
    canvas
    <div data-draggable-canvas data-isdraggable="true" id="canvas">&nbsp;</div>
  </div>
</div>

Here's the JavaScript, which I have set up to load in head, and the example fiddle has in body. Either way, it still errors with the same issue of course, so I'm sure there's no importance there:

app.directive('draggableCanvas', ['$rootScope', function ($rootScope) {
    return {
        restrict: 'A',
        scope: {
            isdraggable: '=',
            kineticObj: '='
        },
        link: function (scope, el, attrs) {
        console.log("in");
            if (!scope.kineticStageObj) {
                var id = attrs["id"];
                //create random unique id
                if (!id) {
                    id = Math.random().toString(36).substring(7);
                }
                if (!scope.kineticStageObj) {
                    scope.kineticStageObj = new Kinetic.Stage({
                        container: id,
                        width: 578,
                        height: 200
                    });
                }
                if (!scope.kineticStageObj.container) {
                    scope.kineticStageObj.attrs.container = id;
                }
            }
            var layer = new Kinetic.Layer();
            var rectX = scope.kineticStageObj.getWidth() / 2 - 50;
            var rectY = scope.kineticStageObj.getHeight() / 2 - 25;

            //if kineticObj is null, init
            var options = {
                x: rectX,
                y: rectY,
                width: 100,
                height: 50,
                fill: '#00D2FF',
                stroke: 'black',
                strokeWidth: 4,
            };
            if (scope.isdraggable) {
                options.draggable = true;
            }
            if (!scope.kineticObj) {
                scope.kineticObj = new Kinetic.Rect(options);
            }

            // add cursor styling
            scope.kineticObj.on('mouseover', function () {

                document.body.style.cursor = 'pointer';

            });
            scope.kineticObj.on('mouseout', function () {
                document.body.style.cursor = 'default';
                $rootScope.$emit("CANVAS-MOUSEOUT");
            });

            layer.add(scope.kineticObj);
            scope.kineticStageObj.add(layer);

        }
    }
}]);

1 Answers1

0

The problem is that you're assigning values to the attributes in the directive.

This was already explained in the accepted answer to this question here.

The way to solve this is to change each attribute to a variable by assigning it to a $scope. Here is your working jsfiddle.

Please note the following changes:

<div data-draggable-canvas kineticobj=canvasKineticObj kineticstageobj=canvasKineticStageObj isdraggable=isDraggable id="canvas">&nbsp;</div>

For each attribute it was assigned a specific scope and those scopes were defined in the controller called canvasCtrl.

app.controller('canvasCtrl', function($scope){
    $scope.canvasKineticObj = false;
    $scope.canvaskineticStageObj = false;
    $scope.isDraggable = true;
});
Community
  • 1
  • 1
pgrodrigues
  • 2,083
  • 1
  • 24
  • 28