Empty array inside controller function called by directive - AngularJS

I have a rather complicated problem that seems trivial, but I can't find a good way to solve it.

Essentially I am creating a to-do list app using Angular and Angular-Material .

I have main.html where the important part is:

<md-content ng-show="mainCtrl.todos.length">
   <md-list class="todo_list" flex>
     <md-subheader class="md-no-sticky">{{mainCtrl.todoList.label}}</md-subheader>
       <acme-todo ng-show="mainCtrl.todos" ng-repeat="todo in mainCtrl.todos track by $index"
                  text="todo.content" index="$index"></acme-todo>
   </md-list>
</md-content>

      

Where acme-todo

is the directive containing the todo.html :

<md-list-item layout='row' layout-sm='column' layout-align='center center' layout-wrap>
    <i class='material-icons md-avatar'>border_color</i>
    <div class='md-list-item-text'><h3>{{mainCtrl.text}}</h3></div>
    <div class='md-secondary'>
        <md-button class='md-fab md-primary md-small box red-btn'
                   aria-label='delete' ng-click='mainCtrl.deleteTodo(mainCtrl.index)'>
            <i class='material-icons small-icon'>highlight_off</i>
        </md-button>
    </div>
</md-list-item>

      

Where todo.directive.js :

(function () {
    'use strict';

    angular
        .module('todoApp')
        .directive('acmeTodo', acmeTodo);

    function acmeTodo() {
        var directive = {
            restrict: 'EA',
            scope: {
                text :  '=',
                index : '='
            },
            templateUrl: 'todo.html',
            controller : 'MainController',
            controllerAs : 'mainCtrl',
            bindToController : true
        };

        return directive;
    }

})();

      

Finally, main.controller.js :

(function () {
    'use strict';

    angular
        .module('todoApp')
        .controller('MainController', MainController);

    function MainController() {

        var vm = this;
        vm.todos = [];

        . . .

        vm.addToDo = addToDo;
        vm.deleteTodo = deleteTodo;

        //vm.todo.content is the ng-model of the input-box
        function addToDo() {
            if( vm.todo && !_.isUndefined(vm.todo.content)){
                   pushNewToDo(vm.todo.content);
            }
        }

        function deleteTodo(index) {
            vm.todos.splice(index, 1);
        }

        function pushNewToDo(todo) {
            vm.todos.push({ content : todo });
            vm.todo.content = '';
        }

    }

})();

      

Everything works fine except for todo deletion. When deleteTodo

, the function correctly accepts external ones $index

from main ng-repeat

, but I cannot find out why, it is vm.todos

empty at this moment, so nothing is deleted.

If instead I can manage to move all of the todo.html content to acme-todo

, everything works fine.

I also tried setting $scope : true

in directive instead of passing both text

and $index

but I am still facing the same problem.

Here is a working Codepen that reproduces my problem. Notabene In CodePen I use template

instead templateUrl

, and I changed the icons just to work correctly there.

Here's the real app screen:

enter image description here

I know that by default, if I don't specify any controller, the directive will still select its scope, but

EDIT

Using Service

or Factory

also solves the problem as in this CodePen solves the problem, but I feel like I am adding too much logic for such a small thing.

Why am I getting an empty todos array, even thinking that both the controller and the directive share the same scope? How can I fix this while maintaining the same approach (using the todo directive)?

+3


source to share


1 answer


You have to separate the application controller and directives because when you initialize a directive you are creating a new controller, so a new locator $scope

and a new one todos

locally inside the directive. After that, you can pass the delete function from the main controller to the directive $scope

.



Take a look here: http://codepen.io/anon/pen/zZWyLV

+1


source







All Articles