2015-06-15 233 views
0

使用angularJS我試圖建立一個列表,將用作菜單。 我有JSON的數組和菜單必須根據JSON的領域條件建:從JSON數組生成HTML列表

在我的控制,現在,我有這樣的:

獲取JSON:

$scope.cartoList = []; 
$http.get('frList.json') 
.success(function(data) { 
    $scope.cartoList = data; 
    $scope.buildMenu(); 
}) 
.error(function(data) { 
    console.log("Error while getting json."); 
}) 

初始化菜單列表:

$scope.initMenu = function() { 
    for (var i = 0; i < $scope.cartoList.length; i++) { 
     if ($scope.cartoList[i].informationSystem != "" && $scope.ISList.indexOf($scope.cartoList[i].informationSystem) === -1) 
      $scope.ISList.push($scope.cartoList[i].informationSystem); 
     if ($scope.cartoList[i].macroProcess != "" && $scope.macroProcessList.indexOf($scope.cartoList[i].macroProcess) === -1) 
      $scope.macroProcessList.push($scope.cartoList[i].macroProcess); 
    } 
} 

JSON示例:

[ 
{ "area" : "Middle", 
    "block" : "Position", 
    "created" : "2015-6-15", 
    "defaultZoom" : "1", 
    "displayName" : "Architecture", 
    "fileName" : "AA_APK", 
    "informationSystem" : "A Group", 
    "lastupdate" : "2015-6-15", 
    "level" : "Block", 
    "macroProcess" : "", 
    "type" : "AA" 
    }, 
    { "area" : "", 
"block" : "", 
"created" : "2015-6-15", 
"defaultZoom" : "1", 
"displayName" : "Processus order VM", 
"fileName" : "AM_Process_order_VM", 
"informationSystem" : "A Group", 
"lastupdate" : "2015-6-15", 
"level" : "", 
"macroProcess" : "Deal period", 
"type" : "AM" 
}, 
... 
] 

HTML:

<ul class="sidebar-menu slimscroll"> 
<li class="treeview" ng-repeat="IS in ISList"><a href="javascript:void(0)"> <i class="fa fa-folder"></i>{{IS}} <i class="fa fa-angle-left pull-right"></i></a> 
     <ul class="treeview-menu"> 

      <li class="treeview"><a href="javascript:void(0)"> <i class="fa fa-folder"></i>Processus<i class="fa fa-angle-left pull-right"></i></a> 
      <ul class="treeview-menu"> 
       <li class="treeview" ng-repeat="mProcess in macroProcessList"><a href="javascript:void(0)"><i class="fa fa-folder"></i>{{mProcess}}<i class="fa fa-angle-left pull-right"></i></a> 
       <ul class="treeview-menu"> 
        <li ng-repeat="carto in cartoList" ng-if="carto.type == 'AM' && carto.macroProcess == mProcess && carto.informationSystem == IS"><a href="javascript:void(0)" ng-click="changeSVG(carto.fileName)"><i class="fa fa-sitemap"></i>{{carto.displayName}}</a></li> 
       </ul> 
       </li> 
      </ul> 
      </li> 

      <!-- Other <li> will come here --> 

     </ul> 
</li> 
</ul> 

問題是菜單,當我點擊我的IS元素降不下來。

treeviewtreeview-menu來自我使用,你可以在這裏找到模板:https://almsaeedstudio.com/themes/AdminLTE/index.html

但我不認爲這是相關的。

編輯: 菜單下拉由JQuery處理,所以它可能是相關的。由於JQuery和angular之間的一些衝突,可能會導致事件沒有被捕獲?

這應該是相關的部分:

$.AdminLTE.tree = function (menu) { 
var _this = this; 

$("li a", $(menu)).on('click', function (e) { 
    //Get the clicked link and the next element 
    var $this = $(this); 
    var checkElement = $this.next(); 

    //Check if the next element is a menu and is visible 
    if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible'))) { 
    //Close the menu 
    checkElement.slideUp('normal', function() { 
     checkElement.removeClass('menu-open'); 
     //Fix the layout in case the sidebar stretches over the height of the window 
     //_this.layout.fix(); 
    }); 
    checkElement.parent("li").removeClass("active"); 
    } 
    //If the menu is not visible 
    else if ((checkElement.is('.treeview-menu')) && (!checkElement.is(':visible'))) { 
    //Get the parent menu 
    var parent = $this.parents('ul').first(); 
    //Close all open menus within the parent 
    var ul = parent.find('ul:visible').slideUp('normal'); 
    //Remove the menu-open class from the parent 
    ul.removeClass('menu-open'); 
    //Get the parent li 
    var parent_li = $this.parent("li"); 

    //Open the target menu and add the menu-open class 
    checkElement.slideDown('normal', function() { 
     //Add the class active to the parent li 
     checkElement.addClass('menu-open'); 
     parent.find('li.active').removeClass('active'); 
     parent_li.addClass('active'); 
     //Fix the layout in case the sidebar stretches over the height of the window 
     _this.layout.fix(); 
    }); 
    } 
    //if this isn't a link, prevent the page from being redirected 
    if (checkElement.is('.treeview-menu')) { 
    e.preventDefault(); 
    } 
}); 
}; 
+1

可以使用NG-重複用於顯示列表。 – simon

+0

我會建議選擇一種策略並持續一致。例如,您使用'innerHTML'並將HTML用作錨點和圖標元素,但是使用DOM方法構造'ul'和'li'。我的建議是創建一個HTML字符串數組,並設置最終的innerHTML一次。 –

+0

編輯過的初始文章,用'ng-repeat'和'ng-if'使用 – Ellone

回答

0

所以是的,問題來自jQuery處理角度應該有的事件。

要解決它,你可以添加ng-click="toggleMenu($event)"<a><li class="treeview"...

然後在控制器添加:

$scope.toggleMenu = function (e) { 
    var elem = angular.element(e.currentTarget); 
    var $this = elem ; 
    var checkElement = $this.next(); 

    //Check if the next element is a menu and is visible 
    if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible'))) { 
    //Close the menu 
    checkElement.slideUp('normal', function() { 
     checkElement.removeClass('menu-open'); 
     //Fix the layout in case the sidebar stretches over the height of the window 
     //_this.layout.fix(); 
    }); 
    checkElement.parent("li").removeClass("active"); 
    } 
    //If the menu is not visible 
    else if ((checkElement.is('.treeview-menu')) && (!checkElement.is(':visible'))) { 
     //Get the parent menu 
     var parent = $this.parents('ul').first(); 
     //Close all open menus within the parent 
     var ul = parent.find('ul:visible').slideUp('normal'); 
     //Remove the menu-open class from the parent 
     ul.removeClass('menu-open'); 
     //Get the parent li 
     var parent_li = $this.parent("li"); 

     //Open the target menu and add the menu-open class 
     checkElement.slideDown('normal', function() { 
     //Add the class active to the parent li 
     checkElement.addClass('menu-open'); 
     parent.find('li.active').removeClass('active'); 
     parent_li.addClass('active'); 
     //Fix the layout in case the sidebar stretches over the height of the window 
     // _this.layout.fix(); 
     }); 
    } 
    //if this isn't a link, prevent the page from being redirected 
    if (checkElement.is('.treeview-menu')) { 
     e.preventDefault(); 
    } 
} 
1

我想你了具有約angularJS有點誤解,以及它可以爲你做什麼。你需要一個很長的路徑來顯示你的菜單,當它讓你的生活變得更簡單時,我想我可以澄清一下爲了讓你的菜單列表能夠繼續下去,可以做些什麼。

AngularJS具有ng-repeat屬性,它允許您訪問控制器中的數組並顯示每個元素的內容。像:

<ul> 
    <li ng-repeat="element in list"> 
     <div class="{{element}}">{{element}}</div> 
    </li> 
</ul> 

這使得您在範圍list變量的每一個元素創建一個li元素。

使用這種功能可以讓您在開發階段更早地看到菜單。從我在場景中看到的情況來看,每個元素都有兩種可能的結果:它不是菜單就是菜單,元素根據它而改變。看看這個小提琴拿到你可以做什麼保持:

http://jsfiddle.net/4xkvq7dj/1/

這個例子是很簡單的,所以你知道你可以做什麼的基礎知識。從那裏開始找出你想要完成的事情。使用DOM在控制器中構建菜單並不是角度的方式,它確實很快就會變得雜亂無章。您可以在HTML中使用ng-repeat和其他角度指令來實現許多事情,因此視圖邏輯保留在視圖=)中。

祝您的項目好運!

+0

嗨,謝謝,我很熟悉'ng-repeat',但我不確定我能用它,因爲我需要使用一些條件在我的JSON領域,我現在知道可以通過'ng-if'實現。 我使用這種新方法更改了我的初始文章,但我遇到了與該菜單相關的另一個問題。如果你有任何想法。 – Ellone