D
D
DizzyJager2014-05-27 12:58:45
Angular
DizzyJager, 2014-05-27 12:58:45

How to get data from an element in AngularJs?

I have a controller with two arrays of objects, say Garages and Cars. Garage can contain Car.

$scope.Model.Garages = garageService.getGarages();
$scope.Model.Cars = garageService.getCars();

In View, Cars elements support dragging in Garage, the 'data-draggable' and 'data-droptarget' directives are responsible for this
module.directive('draggable', ['$rootScope', function ($rootScope) {
    return {
        restrict: 'A',
        link: function (scope, el, attrs, controller) {
            el.attr("draggable", "true");
                
            el.bind("dragstart", function(e) {
                var id = el.attr('data-draggable');

                e.dataTransfer.setData('text', id);
            });
        }
    };
}]);

module.directive('droptarget', ['$rootScope', function ($rootScope) {
    return {
        restrict: 'A',
        scope: {
            onDrop: '&'
        },
        link: function(scope, el, attrs, controller) {
            el.bind("drop", function (e) {
                var sourceElementId = e.dataTransfer.getData("text");
                var sourceElement = document.querySelector('[data-draggable="' + sourceElementId + '"]');

                var targetElement = el;
                
                scope.onDrop({src: sourceElement, dest: targetElement});
            });
        }
    };
}]);

At the end of the dragging, you need to update the data in the controller: move the object from Cars to Garage. To do this, the directive calls the controller method, passing the Car and Garage elements there.
<div class="car" ng-repeat="car in Model.Cars" data-draggable data-on-drop="moveCarToGarage(car, garage)"></div>

What's the best way to get the data these elements are bound to in order to update the controller?
At the moment I'm using the following solution (moveCarToGarage method in the controller):
var carData = angular.element(car).scope().car;
var garageData = angular.element(garage).scope().garage;

garageData.Cars.push(carData);

$scope.apply();

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Sergey, 2014-05-27
@DizzyJager

you need to implement a directive that will be responsible for drag'n'drop of objects, and organize callbacks inside that can be set via scope. (for example, something like on-drop). For ease of setup, you can make several directives, and one main one (read about require).
You can work with elements only in directives, but directives should not know anything about your business logic. That is, if you have constructions of the form angular.element(garage).scope(), then this is a reason to think.
It should turn out something like this:

<ul>
<li data-ng-repeat="car in Model.cars" data-draggable="car" data-draggable-item="car">{{car.modelName}}</li>
</ul>
<ul>
    <li data-ng-repeat="garage in Model.garages"  data-droppable="car" data-on-drop="doSomething">{{garage.name}}</li>
</ul>

the data-draggable and data-droppable attributes will be tagged to indicate which objects can be dropped where. For your task, you can do without it.
// controller
$scope.doSomething = function (car, garage) {
    // ставим машинку в гараж, убираем ее из списка если хотим, или что-то еще...
    // контроллер в этом случае вообще ничего не знает о drag n drop, 
    // только о том что что-то нужно сделать с данными.
};

K
kompi, 2014-05-27
@kompi

Who prevents inside moveCarToGarage (car, garage), loop through the data array and update the matching values?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question