我有这样的分层数据:
[
{
"children":[
{
"children":[...],
[...]
},
{
"children":[...],
[...]
},
],
[...]
}
]
我想通过展平数据来构建树状网格。我正在使用以下指令:
app.directive('tree', function (hierarchyService, logger, $timeout) {
return {
scope: {
data: '='
},
restrict: 'E',
replace: true,
template: '<div>' +
'<table class="table table-striped table-hover">' +
' <thead>' +
' <tr>' +
' <th class="col-md-6">Account name</th>' +
' </tr>' +
' </thead>' +
' <tbody><tr collection data="data" /></tbody>' +
' </table>' +
'</div>'
};
});
app.directive('collection', function() {
return {
restrict: "A",
replace: true,
scope: {
data: '=',
depth: '@'
},
template: '<member ng-repeat="member in data" member="member" depth="{{depth}}" />',
link: function (scope, element, attrs) {
scope.depth = parseInt(scope.depth || 0);
}
}
});
app.directive('member', function($compile) {
return {
restrict: "E",
replace: true,
scope: {
depth: '@',
member: '='
},
template: '<tr ng-class="{selected: member.selected}">' +
'<td>' +
' <span ng-show="depth > 0" style="width: {{depth * 16}}px; display: inline-block;"></span> {{member.name}}' +
'</td>' +
'</tr>',
link: function (scope, element, attrs) {
scope.depth = parseInt(scope.depth || 0);
if (angular.isArray(scope.member.children) && scope.member.children.length > 0) {
var el = angular.element('<tr collection data="member.children" depth="{{newDepth}}" />');
scope.depth = parseInt(scope.depth || 0);
scope.newDepth = scope.depth + 1;
$compile(el)(scope);
// Flatten hierarchy, by appending el to parent
element.parent().append(el);
}
}
}
});
问题是,在通过 link 方法添加的集合中,父范围的 depth 附加到 newDepth。因此,第 3 级节点的 depth 的值为 depth="3 2 1 "。
如何禁止继承depth?
我还注意到,当我在 collection 和 member 指令中将 replace 更改为 false 时,深度按预期工作,但 HTML无效。
最佳答案
有时更简单的解决方案更好。最好将服务中的树状结构展平,然后使用 ng-repeat 迭代新结构。 https://plnkr.co/edit/CiFGZYi6NdH8ZFDiAyPz?p=preview
更简单的代码。不需要所有那些难以理解的指令。此外,您不应该使用 replace with 指令,因为它是 deprecated .
动态设置样式你应该使用ng-style指令。
var app = angular.module('app', []);
app.factory('treeFlatting', function () {
function flattenTree(tree, depth) {
depth = depth || 0;
return tree.reduce(function (rows, node) {
var row = {
name: node.name,
depth: depth,
};
var childrenRows = angular.isArray(node.children) ?
flattenTree(node.children, depth + 1) : [];
return rows.concat(row, childrenRows);
}, []);
}
return flattenTree;
});
app.directive('tree', function (treeFlatting) {
return {
restrict: 'E',
replace: true,
template: '<div>' +
'<table class="table table-striped table-hover">' +
' <thead>' +
' <tr>' +
' <th class="col-md-6">Account name</th>' +
' <th class="col-md-1">Depth</th>' +
' </tr>' +
' </thead>' +
' <tbody>'+
' <tr ng-repeat="row in rows">'+
' <td ng-style="{\'padding-left\': (16 * row.depth) + \'px\'}">{{row.name}}</td>'+
' <td>{{row.depth}}</td>'+
' </tr>'+
' </tbody>' +
' </table>' +
'</div>',
link: function (scope, element, attrs) {
scope.data = [
{
name: 'Root',
children: [
{
name: 'Level 1',
children: [
{
name: 'Level 2'
}
]
}
]
}
];
scope.rows = treeFlatting(scope.data).filter(function (row) {
return row.depth > 0;
});
}
};
});
关于javascript - Angular 追加父属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37270318/
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs
查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用
所以这可能有点令人困惑,但请耐心等待。简而言之,我想遍历具有特定键值的所有属性,然后如果值不为空,则将它们插入到模板中。这是我的代码:属性:#===DefaultfileConfigurations#default['elasticsearch']['default']['ES_USER']=''default['elasticsearch']['default']['ES_GROUP']=''default['elasticsearch']['default']['ES_HEAP_SIZE']=''default['elasticsearch']['default']['MAX_OP
假设我有以下类(class):classPersondefinitialize(name,age)@name=name@age=ageenddefget_agereturn@ageendend我有一组Person对象。是否有一种简洁的、类似于Ruby的方法来获取最小(或最大)年龄的人?如何根据它对它们进行排序? 最佳答案 这样做会:people_array.min_by(&:get_age)people_array.max_by(&:get_age)people_array.sort_by(&:get_age)
我想为我的Task模型创建一个status属性,该属性将按以下顺序指示它在三部分进度中的位置:打开=>进行中=>完成。它的工作方式类似于亚马逊包裹的交付方式:已订购=>已发货=>已交付。我想知道设置此属性的最佳方法是什么。我可能是错的,但创建三个独立的bool属性似乎有点多余。实现此目标的最佳方法是什么? 最佳答案 Rails4有一个内置的enummacro.它使用单个整数列并映射到键列表。classOrderenumstatus:[:ordered,:shipped,:delivered]end状态映射如下:{ordered:0,
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的