角度分组指令的起点

时间:2015-07-02 10:27:21

标签: angularjs angularjs-scope angularjs-ng-repeat angular-directive

我正在尝试使用多个预定义过滤器创建分组和过滤机制。我有一组未定义的规则和一些预定义的分组操作,例如" relativeDate" (今天,明天,昨天,本周......),"布尔"要么 。这组行动应该是可扩展的。

我设法让它在控制器中工作。但是我想把它外包到一个指令中,以使其与其他对象集合一起工作。问题是:我需要动态指定列表的模板。

想象一下以下集合:

$scope.memosReceived = [
     { id: 1, from: 'Henry Ford', title: 'Want your Model T?', received: '2015-05-04T12:30:00', read: true },
     { id: 2, from: 'Oliver Newton', title: 'Look at this!', received: '2015-06-15T08:00:00', read: true }
     ...
];

$scope.memosSent = [
     { id: 1, to: 'Henry Ford', title: 'That is an old car', sent: '2015-05-04T12:35:21', read: true },
     { id: 2, to: 'Oliver Newton', title: 'Stop Spam', sent: '2015-06-15T08:01:47', read: false }
     ...
];

现在标记应如下所示:

<div ng-controller="controller">
    <h2>Received</h2>
    <grouped-list ng-model="memosReceived" item-var="received" grouping-options="groupingReceived">
        <h2>{{ received.title }} <sub>by {{ received.from }}</h2>
    </grouped-list>

    <h2>Sent</h2>
    <grouped-list ng-model="memosSent" item-var="sent" grouping-options="groupingSent">
        <h2>{{ sent.title }} <sub>to {{ sent.to }}</h2>
    </grouped-list>
</div>

选项可能如下:

$scope.groupingReceived = [
    { modelKey: 'received', action: 'relativeDate', options: { [.. passed to grouping action, like value->name mapping ..] },
    { modelKey: 'read', action: 'boolean', options: { [...] } }];

$scope.groupingSent = [
    { modelKey: 'sent', action: 'relativeDate', options: { [.. passed to grouping action, like value->name mapping ..] },
    { modelKey: 'read', action: 'boolean', options: { [...] } }];

呈现的HTML应该如下所示&#34; PseudoHtml&#34;:

<div ng-controller="controller">
    <h2>Received</h2>
    <div class="grouped-list">
        <div class="filter-section">
            <button ng-click="openFilters = !openFilters>Open Filters</button>
            <div class="filter-options" ng-hide="!openFilters">
                <h4>Group by</h4>
                [selectbox given group actions] [selectbox sort ascending or descending]
                <h4>Filter by</h4>
                [build filters by similar to group actions given filter actions]
            </div>
        </div>
        <div class="group">
            <div class="group-header">
                <h3>Yesterday</h3>
            </div>
            <ul class="group-list">
                <li ng-repeat="received in ngModel | customFilters">
                    <!-- something like transclusion starts here -->
                    <h2>{{ received.title }} <sub>by {{ received.from }}</h2>
                    <!-- something like transclusion ends here -->            
                </li>
           </ul>
        </div>
        <div class="group">
            <div class="group-header">
                <h3>Last Week</h3>
            </div>
            <ul class="group-list">
                <li ng-repeat="received in ngModel | customFilters">
                    <!-- something like transclusion starts here -->
                    <h2>{{ received.title }} <sub>by {{ received.from }}</h2>
                    <!-- something like transclusion ends here -->            
                </li>
            </ul>
        </div>
    </div>

    <h2>Sent</h2>
    <div class="grouped-list">
        [... same like above ...]
    </div>
</div>

我真的很擅长如何实现这种行为,在哪里存储逻辑的几个部分(例如分组操作,自定义过滤器)以及如何正确地转换它。

也许有人可以给我一个很好的起点。

1 个答案:

答案 0 :(得分:0)

您可以创建自定义过滤器并从指令的控制器中调用它。

在此过滤器内部,您可以通过将参数传递给过滤器来决定应该触发哪个过滤器操作。

我会从控制器而不是模板中调用它,因为您可以更轻松地链接过滤器。

请查看下面的演示或此jsfiddle

在将代码添加到SO期间,我在我的代码中检测到了一个较新的AngularJS版本的错误(不显示该项目)。不知道它是什么,但1.2.1它正在工作。 我稍后会检查一下。似乎是一个范围问题。

&#13;
&#13;
angular.module('demoApp', [])
    .filter('aw-group', function($filter) {
        var filterMethods = {
            relativeDate: function(input, action) {
                console.log('relative date called', input);
                return input; // do the translation to relative date here
            },
            filterByNumber: function(input, action, options) {
                // if you need mor parameters
                return $filter('filter')(input, options.number);
            },
           otherFilter: {
           }
        };
        
        return function(input, action, options) {
            return filterMethods[action](input, action, options);
        };
    })   
    .directive('groupedList', function () {
    return {
        restrict: 'E',
        scope: {
            model: '=',
            itemVar: '=',
            filter: '='
        },
        transclude: true,
        template: '<ul><li ng-repeat="item in filteredModel" ng-transclude>'+
        '</li></ul>',
        controller: function($scope, $filter) {
            //console.log($scope.filter);
            
            $scope.filteredModel = $filter('aw-group')($scope.model, 'filterByNumber', { number: 2 }); // passing action from $scope.filter.action as second parameter, third is an options object
        }
    };
})
    .controller('mainController', function () {
    this.data = [{
        title: 'Test1',
        from: 'tester1'
    }, {
        title: 'Test2',
        from: 'tester1'
    }, {
        title: 'Test3',
        from: 'tester1'
    }, ];
    this.groupingReceived = [{
        modelKey: 'received',
        action: 'relativeDate',
        options: {},
        modelKey: 'read',
        action: 'boolean',
        options: {}
    }];

    this.memosReceived = [{
        id: 1,
        from: 'Henry Ford',
        title: 'Want your Model T?',
        received: '2015-05-04T12:30:00',
        read: true
    }, {
        id: 2,
        from: 'Oliver Newton',
        title: 'Look at this!',
        received: '2015-06-15T08:00:00',
        read: true
    }];

});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="mainController as ctrl">
    <grouped-list model="ctrl.data" item-var="received" filter="ctrl.groupingReceived">
         <h2>{{item.title}}<sub>{{item.from}}</sub></h2>

    </grouped-list>
</div>
&#13;
&#13;
&#13;