替代内容指令 - 范围问题
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' 可能会有一些缺点,但最终结果似乎足够好,不会你说?
;)
我正在尝试制定一个指令,根据单个标记为不同的设备提供替代内容,以避免重复代码,例如使内容列表在大屏幕上显示为选项卡或在小屏幕上显示为手风琴。
<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' 可能会有一些缺点,但最终结果似乎足够好,不会你说?
;)