我正在创建一个花哨的滑块,允许用户选择范围内的值,我正在尝试将其构建为AngularJS指令。范围中的每个步骤都有一个简短的文本描述,显示在该位置。例如:
Temperature
Warm
[------------------^------]
| | | | |
Cold Hot
我想在页面上使用这个初始标记,因为它是语义的并且优雅地降级:
<div class="prompt scale">
<label for="mySelect">Temperature</label>
<select name="mySelect">
<option value="1">Cold</option>
<option value="2">Cool</option>
<option value="3">Neutral</option>
<option value="4">Warm</option>
<option value="5">Hot</option>
</select>
</div>
然后我会用花式滑块的标记完全替换它。但是,这样做需要Angular能够读取原始标记,以便提取渲染花式滑块所需的数据(每个选项的值和标签)。但是,我找不到任何可以引用原始元素及其子元素的地方。声明该指令时,compile()和link()函数都引用模板元素,而不是原始元素。如何阅读原始标记,包括访问其后代?
答案 0 :(得分:2)
如果您打算在指令配置对象上使用模板属性,我猜您将失去查看原始属性的能力。
我认为要有效地做你正在做的事情,你需要使用我不熟悉的编译指令功能。我没有用它来告诉你这个:
基本上为每个重要数据创建指令。让他们共享一个控制器来注册所有这些数据。通过这种方式,父指令可以使其子节点不一定是指定的深度。隐藏(或删除,如果您愿意)原始标记,然后根据合并信息创建窗口小部件。
在你的情况下,我会像你在这里看到的那样连接所有内容的指令和另一个指针,它本身就是小部件,可以用可能的属性或配置对象创建,就像另一个回答者建议的那样。 / p>
<div>
<div sliding-scale class="prompt scale">
<label sliding-scale-title for="mySelect">Temperature</label>
<select name="mySelect">
<option sliding-scale-option value="1">Cold</option>
<option sliding-scale-option value="2">Cool</option>
<option sliding-scale-option value="3">Neutral</option>
<option sliding-scale-option value="4">Warm</option>
<option sliding-scale-option value="5">Hot</option>
</select>
</div>
</div>
var myApp = angular.module('myApp', []);
myApp.directive('slidingScaleTitle', function () {
return {
require: '^slidingScale',
link: function (scope, element, attrs, controller) {
controller.setTitle(element.text());
}
};
});
myApp.directive('slidingScaleOption', function () {
return {
require: '^slidingScale',
link: function (scope, element, attrs, controller) {
controller.addOption({
value: attrs.value,
text: element.text()
});
}
};
});
myApp.directive('slidingScale', function ($compile) {
var template = '<div><b>{{ title }}</b><ul><li ng-repeat="o in options"><b>{{ o.value }}:</b> {{ o.text }} </li></ul>';
return {
// You should make this its own controller if you want this unit-tested.
// I'm inlining it as an example.
controller: function ($scope) {
var title;
var options = [];
this.setTitle = function (value) {
title = value;
};
this.getTitle = function () {
return title;
};
this.getOptions = function () {
return options;
}
this.addOption = function (value) {
options.push(value);
};
},
link: function (scope, element, attrs, controller) {
scope.$watch(controller.getTitle, function (value) {
scope.title = value;
});
scope.$watch(controller.getOptions, function (value) {
scope.options = value;
});
element.children().css('display', 'none');
fancySliderElement = angular.element(template);
element.append(fancySliderElement);
$compile(fancySliderElement)(scope);
}
}
});