替代内容指令 - 范围问题

Alternative content directive - Scope issues

我正在尝试制定一个指令,根据单个标记为不同的设备提供替代内容,以避免重复代码,例如使内容列表在大屏幕上显示为选项卡或在小屏幕上显示为手风琴。

<collection>
  <item>A</item>
</collection>

进入

<main-version>
   <m-ver-item>A</m-ver-item>
</main-version>
<alternative-version>
  <alt-ver-item>A</alt-ver-item>
</alternative-version>

我用我目前所拥有的东西做了一个 plunker,例如,目前正在尝试使用 ng-repeat 失败。

Plnkr:http://plnkr.co/edit/1IgG2YCn1b8j3HyeMiKy?p=preview

JS Fiddle: http://jsfiddle.net/p65se0cp/

问候

这似乎有效:

http://jsfiddle.net/3u3h64fw/1/

我使用了包含并添加了一个 tab-group-responsive-item 指令来替换 item:

HTML:

<tab-group-responsive>
    <tab-group-responsive-item heading="Notes33">
        <div>
            <h2 ng-bind="title"></h2>
            <span ng-repeat="note1 in notes">
                <b>{{note1.Content}}</b><br/>
            </span>
        </div>
    </tab-group-responsive-item>
    <tab-group-responsive-item heading="wep"><a ng-click="func()">call func</a></tab-group-responsive-item>
</tab-group-responsive>

JS:

angular.module("test",[])
.controller("MyController", ["$scope", function($scope) {
    $scope.notes = [{Content: "Lorem Ipsum"},{Content: "Sit amet"}];
    $scope.func=function() {
        $scope.notes.push({Content: "Added by func"});
    };
    $scope.title="Title";
}])
.directive("tabGroupResponsive", function () {
    return directive = {
        restrict: 'EA',
        scope: true,
        transclude: true,
        templateUrl: '/customTemplate/tabset-responsive.html'
    }
})
.directive("tabGroupResponsiveItem", function ($animate) {
    return directive = {
        restrict: 'EA',
        scope: true,
        transclude: true,
        link: function ($scope, $element, attrs, ctrl, $transclude) {
            $transclude(function(clone, scope) {
                var elt;
                if ($element.parent()[0].tagName.toLowerCase() === 'accordion') {
                    elt = angular.element("<accordion-group heading=" + attrs.heading + "></accordion-group>");
                } else if ($element.parent()[0].tagName.toLowerCase() === 'tabset') {
                    elt = angular.element("<tab heading=" + attrs.heading + "></tab>");
                }
                elt.append(clone);
                $animate.enter(elt, null, $element);
                $element.remove();
            });
        }
    }
})
.run(["$templateCache", function ($templateCache) {
   $templateCache.put("/customTemplate/tabset-responsive.html",
        "<div><div class=\"visible-xs\">" +
            "<accordion ng-transclude>" +
            "</accordion>" +
        "</div>" +
        "<div class=\"hidden-xs\">" +
            "<tabset ng-transclude>" +
            "</tabset>" +
        "</div>" +
        "</div>");
}]);

它应该是一个足够好的开始来实现您正在寻找的东西。不过仍有改进的空间。

这是我回答的另一个版本,因此适用于 bootstrap。

Bootstrap 定义了一个 tabset 嵌入指令,这就是为什么我之前的答案不起作用。

同样适用于 accordion

http://jsfiddle.net/3u3h64fw/5/

HTML:

    <div ng-controller="MyController">
        <tab-group>
            <tab-group-item heading="Notes33">
                <div>
                    <h2 ng-bind="title"></h2>
                    <span ng-repeat="note1 in notes">
                        <b>{{note1.Content}}</b><br/>
                    </span>
                </div>
            </tab-group-item>
            <tab-group-item heading="wep"><a ng-click="func()">call func</a></tab-group-item>
        </tab-group>
    </div>

JS:

   angular.module("test",["ui.bootstrap"])
    .controller("MyController", ["$scope", function($scope) {
        $scope.notes = [{Content: "Lorem Ipsum"},{Content: "Sit amet"}];
        $scope.func=function() {
            $scope.notes.push({Content: "Added by func"});
        };
        $scope.title="Title";
    }])
    .directive("tabGroup", function () {
        return directive = {
            restrict: 'EA',
            scope: true,
            transclude: true,
            templateUrl: '/customTemplate/tabset-responsive.html'
        }
    })
    .directive("tabGroupItem", function ($animate) {
        return directive = {
            require: ['^^?tabset', '^^?accordion'],
            restrict: 'EA',
            scope: true,
            transclude: true,
            link: function ($scope, $element, attrs, ctrl, $transclude) {
                var tabsetCtrl = ctrl[0],
                    accordionCtrl = ctrl[1]
                ;
                $transclude(function(clone, scope) {
                    var elt;
                    if (accordionCtrl) {
                        elt = angular.element("<accordion-group heading=" + attrs.heading + "></accordion-group>");
                    } else if (tabsetCtrl) {
                        elt = angular.element("<tab heading=" + attrs.heading + "></tab>");
                    }
                    if (!elt) {
                        return ;
                    }
                    elt.append(clone);
                    $animate.enter(elt, null, $element);
                    $element.remove();
                });
            }
        }
    })
    .run(["$templateCache", function ($templateCache) {
       $templateCache.put("/customTemplate/tabset-responsive.html",
            "<div><div class=\"visible-xs\">" +
                "<accordion><div ng-transclude></div>" +
                "</accordion>" +
            "</div>" +
            "<div class=\"hidden-xs\">" +
                "<tabset><div ng-transclude></div>" +
                "</tabset>" +
            "</div>" +
            "</div>");
    }]);

变化是:

  • 模板中的 ng-include 属性现在位于内部 div 中(因为 tabset 必须嵌入其内容)

  • tabGroupItem 需要一个可选的父级 tabset 控制器来检测其父级是否为 tabset

同样适用于 accordion

像这样的东西可以代替吗?

angular.module("main", ["ui.bootstrap"])
.controller("MyController", ["$scope", function($scope) {
    $scope.notes = [{Content: "Lorem Ipsum"},{Content: "Sit amet"}];
    $scope.func=function() { alert("function executed")};
    $scope.title="Title";
}])
.directive("tabGroupResponsive", function () {
    return {
        restrict: 'EA',
        template: function (element, attr) {

            children = element.children();
            var html = "";

            html += "<div>";

            html += "<div class=\"visible-xs\">";
            html += "<accordion>";
            for (var i = 0; i < children.length; i++) {
                var child = children[i];

                html += "<accordion-group heading=\"" + child.getAttribute("heading") +"\">";
                html += child.innerHTML;
                html += "</accordion-group>";

            }
            html += "</accordion>";
            html += "</div>";

            html += "<div class=\"hidden-xs\">";
            html += "<tabset>";
            for (var i = 0; i < children.length; i++) {
                var child = children[i];

                html +=  "<tab heading=\"" + child.getAttribute("heading") +"\">";
                html += child.innerHTML;
                html += "</tab>";
            }
            html += "</tabset>";
            html += "</div>";

            html += "</div>";


            return html;
        }
    }
});

http://plnkr.co/edit/DHTcQD12DvBqP1hhVotb?p=preview

我没有这方面的经验,所以我确信像这样使用 'template' 可能会有一些缺点,但最终结果似乎足够好,不会你说?

;)