AngularJS - 使用带有ng Repeat的隔离指令范围

时间:2014-02-19 18:35:03

标签: javascript angularjs

我对Angular很新,我正在尝试将自己的'selectable'指令添加到列表中,以便可以选择或不选择列表中的项目。我一直在尝试保持模块化,所以我宁愿将它存储在'selectable'指令的范围内,而不是将信息存储在列表项中。

我的HTML:

<ul ng-controller="mainCtl">
<li inner="{item: item}" ng-repeat="item in items" ng-class="{sel: inner.selected}">
    {{ item.Name }}
</li>
</ul>

我的'内在'指令:

    directive('inner', [
    function() {
        return {
            restrict: 'A',
            scope: {
                inner: '='
            },
            link: function(scope, element, attr) {
                scope.inner.selected = false;
                element.bind('click', function(e) {
                    scope.inner.selected = !scope.inner.selected;
                });
            }
        };
    }]);

正如你所看到的,我打算让每一行都有一个togglable属性,然后由ngClass用来设置元素的类,而不是存储在'item'对象中。

如果我选择一个示例列表条目,并查看范围内的内容,我看不到“内部”,所以ng-class无法访问它。我有可能完全以错误的方式解决这个问题,因为我并没有完全习惯于“有棱有角”的做事方式。任何有关如何解决这个问题的帮助,或指向我正确的文献方向都会有所帮助。

JSFiddle示例: http://jsfiddle.net/2pdvs/

由于

3 个答案:

答案 0 :(得分:4)

指令非常棒,但在这种情况下你真的需要一个吗?你可以这么做:

<ul ng-controller="mainCtl">
    <li ng-click="selected=!selected" ng-repeat="item in items" ng-class="{sel: selected}">
        {{ item.Name }}
    </li>
</ul>

ng-repeat为每个项目创建一个新范围,因此selected变量将彼此独立地存在于每个列表项中。

答案 1 :(得分:1)

你的指令都有自己的范围,原样。您正在 范围内正确设置bool,但尝试使用ng-class从控制器范围引用它。

有很多方法可以做到这一点,如果你想把它保留在指令中你可以简单地这样做:

angular.module('test', []).
    controller('mainCtl', ['$scope',
        function($scope) {
            $scope.items = [{Name: 'obj1'}, {Name: 'obj2'}];
            console.log($scope);
        }]).
    directive('inner', [
        function () {
            return {
                restrict: 'A',
                scope: {
                    inner: '='
                },
                link: function (scope, element, attr) {
                    var el = angular.element(element);
                    el.on('click', function (a, b, c) {
                        if (el.hasClass('sel')) {
                            el.removeClass('sel');
                        } else {
                            el.addClass('sel');
                        }
                    });
                }
            };
        }]);

工作小提琴:

http://jsfiddle.net/jon23781/2pdvs/4/


否则我会使用@Strille回答

答案 2 :(得分:0)

这是一个适合你的小提琴。

http://jsfiddle.net/TEYTG/

与Asok的回答不同,我仍然设法保留ng-class。我认为你的问题是你没有传递正确的变量而你在ng-class中使用的变量inner超出了它的范围(指令的孤立范围)。

修改

这是一种不使用指令的建议替代方法,它仍然非常模糊,所以我只给出伪代码。我们的想法是创建某种工厂,它接受数组并为它们附加某种选择逻辑。

app.service('selection', [function(){
    function selection(array){
       //constructor function that attaches or creates the selection logic for the array
    }


    this.create = function(input){
        return new selection(input);
    }
}]);

app.controller('myCtrl', ['selection', '$scope', function(selection, $scope){
    $scope.array = [{...},{...}];


    //Creates a selection from the array
    $scope.selection=selection.create($scope.array);
}])

这个想法是服务中的selection函数将获取数组并将选择逻辑附加到它(即将selected=false属性附加到每个对象,创建一个允许切换选择的函数一个对象,取消选择所有项目的函数,或者确定是否至少选择了数组中的某些元素。

虽然这可能看起来要复杂得多(但确实如此),我相信只要你想从列表中选择就可以轻松重复使用。