2015-08-15 99 views
3

我想在AngularJS中創建一個使用嵌套ToDos的ToDo應用程序。作爲其中的一部分,我希望能夠通過點擊來縮進或縮小ToDo(最終,它會對「標籤」或「shift-tab」按鍵做出反應)。當縮進時,該函數還應縮進任何子ToDos。這是我遇到麻煩的地方。我不知道如何在指令中實現遞歸函數。如果任何人看到了這一點或可以提供任何幫助,我將不勝感激。我創建了一個工作的JSFiddle,它縮進了一個ToDo,但不縮進它的子節點。 JS小提琴在這裏https://jsfiddle.net/t1ba50k6/16/如何在angularJS的指令中使用遞歸函數?

此外,請提供有關編碼約定或清理指令的任何最佳做法。

謝謝!

我的HTML:

<ul id=Todos ng-app="app" ng-controller="todos"> 
    <div ng-repeat='todo in model' ng-init="todoIndex = $index"> 
     <todo-item content="todo"></todo-item> 
    </div> 

我的javascript:

var app = angular.module('app', []); 

app.controller("todos", function ($scope) { 

    $scope.model = [{ 
     "title": "Task item one", 
      "indentLevel": 1 
    }, { 
     "title": "Task item two", 
      "indentLevel": 2 
    }, { 
     "title": "Task item three", 
      "indentLevel": 2 
    }]; 

}); 


app.directive('todoItem', function ($compile) { 

    var getTemplate = function (content) { 
     var startStr = ''; 
     var endStr = ''; 

     if (content.indentLevel == 1) { 
      startStr = '<li class="todolist"><table><tr><td><div class="checkboxpadding"><img width="16" height="16" class="checkbox"></div></td><td><div ng-click="indent()">'; 
      endStr = '</div></td></tr></table></li>'; 

      return startStr + content.title + endStr; 
     } else if (content.indentLevel == 2) { 

      startStr = '<li class="todolist indent_2""><table><tr><td><div class="checkboxpadding"><img width="16" height="16" class="checkbox"></div></td><td><div ng-click="indent()">'; 
      endStr = '</div></td></tr></table></li>'; 
      return startStr + content.title + endStr; 
     } 


    }; 

    var linker = function (scope, element, attrs) { 

     element.html(getTemplate(scope.content)).show(); 
     $compile(element.contents())(scope); 


     scope.indent = function() { 
      var childElem = angular.element(element.children()[0]); 

      if (scope.content.indentLevel < 3) { 
       childElem.removeClass("indent_" + scope.content.indentLevel); 
       childElem.addClass("indent_" + (scope.content.indentLevel + 1)); 
       scope.content.indentLevel++; 
       // update Database 
       // indent child nodes? 
       // for (var i=0; i < nodes; i++) {      } 

      } 
     }; 


    }; 

    return { 
     restrict: "E", 
     link: linker, 
     scope: { 
      content: '=' 
     } 
    }; 
}); 

回答

1

映射您的數據嵌套結構將大大簡化了這一點。

總是使用相同的屬性名稱爲孩子陣列:

$scope.model = [{ 
     "title": "Task item one", 
     "indentLevel": 1, 
     "children": [ 
      { 
       "title": "Task item two", 
       "indentLevel": 2, 
       "children":[] 
      }, { 
       "title": "Task item three", 
       "indentLevel": 2, 
       "children":[] 
      } 
     ] 
}]; 
+0

同意。我可以使用這樣的結構。但是,如何在引用孩子的指令中調用函數? – ChrisL

+0

只對孩子使用'ng-repeat'。 google'angular recursive directive'會發現很多結果 – charlietfl

0

一種解決方案是使用$broadcast(name, args)scope$on(name, listener)

cliked火災的事件時:

scope.$broadcast('indent'); 
兒童指令

scope.$on('indent', scope.indent); 
+0

謝謝。我會嘗試,並更新我的小提琴,如果它的作品。 – ChrisL