我发现这是一个有用的模式:
写为角度指令的小部件:
MyApp.directive('parentWidget', function () {
return {
controller: function ($scope) {
$scope.widgets = [{n: 1}, {n: 2}, {n: 3}];
}
};
});
MyApp.directive('childWidget', function () {
return {
scope: {myAttr: '@myAttr'},
controller: function ($scope) {
$scope.dynamicValue = function () {
return 'dynamic';
};
}
};
});
父窗口小部件包含在页面中,如下所示:
<table parent-widget></table>
父窗口小部件的模板如下所示:
<thead>
<tr>
<th>The Dynamic Column</th>
<th>The Static Column</th>
</tr>
</thead>
<tbody>
<tr child-widget
ng-repeat="w in widgets | orderBy:n"
my-attr="{{w.n}}">
</tr>
</tbody>
子窗口小部件的模板如下所示:
<td>{{ dynamicValue() }}</td>
<td>{{ myAttr }}</td>
我的问题:如何在子窗口小部件的动态值上订购表格?我很乐意在静态值上这样做,如图所示。
我唯一能想到的就是使用jquery来操纵<tr>
s之后的事实,这是非常无角度的。
编辑:一些有用的评论者证实了我的怀疑,即无法做到这一点。所以我想我的问题是,重构这种模式以允许这种排序的最佳方法是什么?我宁愿继续分离关注点,即dynamicValue()是子窗口小部件的一个问题,代码应该反映出来。
已解决:接受的答案有几个有用的线索。特别是,在子指令的范围内使用双向绑定以及在DOM上对模型进行排序的建议。我必须添加一个$watch
来实现它,见下文。如果他们可以改进这一点,我很乐意听到任何人的评论。
答案 0 :(得分:1)
如果你想修改孩子们能够按他们排序,那么就把他们作为对象传递而不是属性。
<tr ... my-attr="w"></tr>
并且
<td>{{ myAttr.dynamicValue }}</td><td>{{ myAttr.n }}</td>
jsfiddle :http://jsfiddle.net/4J2aw/
答案 1 :(得分:1)
解决问题的方法:
如果您想以角度方式执行此操作,请将排序应用于模型,而不是应用于已呈现到页面中的<tr>
元素。唯一知道模型完整相关部分的地方是父窗口小部件的控制器,这就是排序必须发生的地方。
<强>后果:强>
为了能够排序,您当然需要访问指令生成的动态值,但这不是问题,因为您的指令可以在他们看到的模型的片段内设置动态值。但是,他们必须能够将值写入其窗口小部件对象(模型):
MyApp.directive('parentWidget', function () {
return {
controller: function ($scope) {
// init the dynamic values with null to make explicit that they
// are part of the model
$scope.widgets = [{n: 1, d: null}, {n: 2, d: null}, {n: 3, d: null}];
}
};
});
MyApp.directive('childWidget', function () {
return {
scope: {
myAttr: '@',
dynamicValue: '='
},
controller: function ($scope) {
// assign the function here or a static value. Whatever works best for you.
$scope.dynamicValue = function () {
return 'dynamic';
};
}
};
});
当然,您可以在模板中参数化您的指令:
<tr child-widget
ng-repeat="w in widgets | orderBy:n"
my-attr="{{w.n}}"
dynamic-value="w.d">
</tr>
就我而言,我更愿意将实际的动态值写入模型而不是计算它的函数,但是如注释中所示,如果您进行相应的排序,两者都将有效。