我有一个旧的jQuery插件我写道,我现在希望将类似的功能转移到角度指令。长话短说我希望它将select标签转换为以下HTML。
<div class="a">
<span class="b" />
<span class="c">{{text}}</span>
<select></select> <!-- this is the original select -->
</div>
选择看起来与此相似:
<select data-ng-options="s.SomeValue as s.SomeLabel for s in someScopeArray"
data-ng-change="notifyForSomeFun()" data-ng-model="someValue"></select>
我试图使用&#34;链接&#34;在新指令上运行,只需执行相同类型的jQuery包装,然后添加我想要的<select>
周围的HTML,就像我在普通的jQuery插件中所做的那样,但是我开始分解的地方需要更新应用于ng-model
的{{1}},并更新<select>
上的{{text}}
绑定。
这是我最近的一次拙劣尝试:
<span class="c">
我是第一个承认,当谈到指令时,我的头脑正在爆炸。我知道我在范围方面存在某种问题。当前版本会在var selectWrapperDirective = function () {
return {
restrict: 'A',
scope: true,
link: function (scope, element, attrs) {
var $this = element;
var defaults = {
containerClass: 'selectWrapper',
labelClass: 'label',
dropImageClass: 'dropImage'
};
var itemText = function () {
return $this.find('option:selected').text();
};
var opts = angular.extend({}, defaults, scope.$eval('{' + attrs.selectWrapper + '}'));
var oldNgChange = attrs['ngChange'];
var ngModel = attrs['ngModel'];
if (ngModel) {
console.log('setting new ngmodel');
attrs.$set('ngModel', '$parent.' + ngModel);
}
// wrap it in a div and add the class, add a span with label class, add a span with dropimage class
$this.wrap('<div class="' + opts.containerClass + '" />');
var container = $this.parent();
container.prepend('<span class="' + opts.dropImageClass + '" />');
container.prepend('<span class="' + opts.labelClass + '">' + itemText() + '</span>');
attrs.$set('ngChange', 'onItemChanged()');
scope.onItemChanged = function () {
console.log('onItemChanged fired');
$this.closest('div').find('.' + opts.labelClass).text(itemText());
if (oldNgChange)
scope.$parent.$eval(oldNgChange);
};
}
}
};
触发时更新{{text}}
,但不会更新父级中的模型。我需要在整个页面中使用这个指令多次与一堆不同的模型,所以我认为我需要某种孤立的范围。 HALP!
修改的 我已经接受了Chad Robinson的回答并在那里发表评论。最终他的答案与AngularJS: Dropdown directive with custom ng-options的SO问题/答案配对,这是我解决问题的原因。
onItemChanged
答案 0 :(得分:2)
有可能完成你的开始,但是你正在跳过很多关于AngularJS的方法。考虑使用<my-select>
而不是<select>
之类的内容。然后你可以做类似的事情:
var selectWrapperDirective = function () {
return {
restrict: 'E',
replace: true,
template: '<div class="a"><span class="b" />' +
'<span class="c">{{text}}</span>' +
'<select></select></div>',
link: function ($scope, iElement, iattrs) {
// ...
}
};
};
当Angular编译你的指令时,它会插入模板中的所有内容,然后运行你的链接功能。您仍然可以使用最初想要应用于模板内<select>
元素的任何/所有属性,并且您仍然可以在事物上注册更改侦听器,尽管您通常会执行<select ng-change="selectionChanged();"></select>
之类的操作并定义{链接函数中的{1}} - 它可以直接手动绑定元素更改事件,从而节省了大量工作。
IMO元素指令是AngularJS的三个或四个最大优势之一 - 它们为您提供当今聚合物/ WebComponents所有人正在努力的一切,并且功能非常强大。在这里不使用它们是一种耻辱,因为你的用例只是尖叫着他们的名字......