angular.js conditional markup in ng-repeat

前端 未结 3 754
遇见更好的自我
遇见更好的自我 2020-12-13 07:37

I\'m using angular.js and (for the sake of argument) bootstrap. Now I need to iterate on \"things\" and display them in \'\'rows\'\' :

3条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-13 08:27

    I recommend a directive for a couple of reasons:

    • it can be reused and parameterized in the HTML (i.e., "every 3rd thing" can be a directive attribute)
    • it does not require any controller code/$scope properties, and hence it does not require recalculation of controller $scope properties if the "things" array changes in size

    Here is a suggested element directive:

    
    

    In the implementation I used code similar to your server-side example:

    myApp.directive('rowGenerator', function() {
        var rowTemplate = '
    ', colTemplate = '
    '; return { restrict: 'E', // use '=' for colCount instead of '@' so that we don't // have to use attr.$observe() in the link function scope: { rowData: '=', colCount: '='}, link: function(scope, element) { // To save CPU time, we'll just watch the overall // length of the rowData array for changes. You // may need to watch more. scope.$watch('rowData.length', function(value) { var html = rowTemplate; for(var i=0; i < scope.rowData.length; i++) { html += colTemplate + scope.rowData[i].key + '
    '; if (i % scope.colCount == scope.colCount - 1) { html += '
    ' + rowTemplate; } } html += '
    '; // don't use replaceWith() as the $watch // above will not work -- use html() instead element.html(html); }) } } });

    Data:

    $scope.things = [
        {key: 'one'},
        {key: 'two'},
        {key: 3},
        {key: 4},
        {key: 'five'},
        {key: 'six'},
        {key: 77},
        {key: 8}    
    ];
    

    Fiddle

    To be efficient, the directive as shown only looks for changes to the length of the rowData (i.e., things) array. If you want to have the directive update the view if the value of one of the array elements changes, you'll need a more expensive $watch:

    scope.$watch('rowData', function(value){ ... }, true)
    

    The true at the end does "shallow" dirty checking ("compares the object for equality rather than for reference) -- see docs.

    There's one thing I don't like about the directive -- it needs to know that rowData entries have a property with name key:

    html += colTemplate + scope.rowData[i].key + '
';

提交回复
热议问题