从指令调用控制器函数内的空数组 - AngularJS

时间:2017-03-22 09:26:41

标签: javascript angularjs angularjs-directive angularjs-scope angular-material

我有一个相当棘手的问题似乎很微不足道,但我找不到一个好方法来解决它。

基本上,我使用 Angular Angular-Material 构建待办事项列表应用程序。

我有一个 main.html ,其中重要的部分是:

<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>

其中acme-todo是包含 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>

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

})();

最后, 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 = '';
        }

    }

})();
  

除非删除待办事项,否则一切正常。何时deleteTodo   被调用时,函数正确接收外部$index   主要的ng-repeat但是,无法找出原因,vm.todos是空的   那一刻,所以,没有任何东西被删除。

相反,如果我设法在acme-todo地方移动所有 todo.html 内容,那么一切正常。

我还尝试在指令中设置$scope : true,而不是同时传递text$index,但我仍遇到同样的问题。

这是一个有效的Codepen,可以重现我的问题。注:在CodePen上我使用template代替templateUrl而我更改了图标只是为了让事情在那里正常工作。

这是一个真实应用程序的屏幕:

enter image description here

我知道,默认情况下,如果我没有指定任何控制器,该指令仍将选择其范围,但

修改

使用ServiceFactory也解决了this CodePen中的问题,解决了这个问题,但我想为这么小的事情添加过多的逻辑。

为什么我会得到一个空的todos数组,即使控制器和指令共享相同的范围?如何修复保持相同方法(使用todo指令)?

1 个答案:

答案 0 :(得分:1)

你应该分开应用程序和指令控制器,因为当你初始化指令时,你要创建新的控制器,所以新的$scope和新的todos数组在本地指令内。之后,您可以将删除功能从主控制器传递到指令$scope

看看这里:http://codepen.io/anon/pen/zZWyLV