我正在做一个点击和删除功能--在页面上,模块是以递归的方式使用的,因此它有一个父和子模块。
我遇到了一个问题,如果用户开始选择孩子-然后选择父-我想取消选择孩子。虽然我不确定如何存储或监视为进行全局取消选举而选择的父/子项中的更改。
因此,用户已经选择了bacon3的子级。如果他们选择了父母--它需要取消选择孩子--但是我觉得我现在被锁在模块的范围里了。

发布于 2018-09-30 23:50:07
我认为这个例子将帮助您https://canary.ember-twiddle.com/468a737efbbf447966dd83ac734f62ad?openFiles=utils.tree-helpers.js%2C
所以,这是一个有趣的问题。结果发现,它更多地是一个递归问题,而不是任何与成员、javascript或复选框行为有关的问题。
以下是我所拥有的(使用更新的语法等等)(如果您可以选择升级到3.4,您肯定应该--这是一个梦想)
// wrapping-component.js
import Component from '@ember/component';
import { action, computed } from '@ember-decorators/object';
import { check } from 'twiddle/utils/tree-helpers';
export default class extends Component {
options = [{
id: 1,
label: 'burger',
checked: false,
children: [{
id: 3,
label: 'tomato',
checked: false
}, {
id: 4,
label: 'lettus',
checked: false
}, {
id: 5,
label: 'pickle',
checked: false
}]
}, {
id: 2,
label: 'kebab',
checked: false,
children: [{
id: 6,
label: 'ketchup',
checked: false
}, {
id: 7,
label: 'chilli',
checked: false
}]
}];
@action
toggleChecked(id) {
const newTree = check(this.options, id);
this.set('options', newTree);
}
}模板:
{{yield this.options (action this.toggleChecked)}}以及使用情况:
// application.hbs
<WrappingComponent as |options toggle|>
{{#each options as |item|}}
<CheckboxGroup @item={{item}} @onClick={{toggle}} />
{{/each}}
</WrappingComponent>CheckboxGroup是一个只使用模板的组件:
// checkbox-group.hbs
<div class="checkboxhandler">
<input
type="checkbox"
checked={{@item.checked}}
onclick={{action @onClick @item.id}}
>
<label>{{@item.label}}</label>
{{#if @item.children}}
{{#each @item.children as |child|}}
<CheckboxGroup @item={{child}} @onClick={{@onClick}} />
{{/each}}
{{/if}}
</div>以及递归帮助程序(这很混乱,但我只是在做原型):
// utils/tree-helpers.js
const toggle = value => !value;
const disable = () => false;
// the roots / siblings are contained by arrays
export function check(tree, id, transform = toggle) {
if (tree === undefined) return undefined;
if (Array.isArray(tree)) {
return selectOnlySubtree(tree, id, transform);
}
if (tree.id === id || id === 'all') {
return checkNode(tree, id, transform);
}
if (tree.children) {
return checkChildren(tree, id, transform);
}
return tree;
}
function selectOnlySubtree(tree, id, transform) {
return tree.map(subTree => {
const newTree = check(subTree, id, transform);
if (!newTree.children || (transform !== disable && didChange(newTree, subTree))) {
return newTree;
}
return disableTree(subTree);
});
}
function isTargetAtThisLevel(tree, id) {
return tree.map(t => t.id).includes(id);
}
function checkNode(tree, id, transform) {
return {
...tree,
checked: transform(tree.checked),
children: disableTree(tree.children)
};
}
function disableTree(tree) {
return check(tree, 'all', disable);
}
function checkChildren(tree, id, transform) {
return {
...tree,
checked: id === 'all' ? transform(tree.checked) : tree.checked,
children: check(tree.children, id, transform)
};
}
export function didChange(treeA, treeB) {
const rootsChanged = treeA.checked !== treeB.checked;
if (rootsChanged) return true;
if (treeA.children && treeB.children) {
const compares = treeA.children.map((childA, index) => {
return didChange(childA, treeB.children[index]);
});
const nothingChanged = compares.every(v => v === false);
return !nothingChanged;
}
return false;
}希望这能有所帮助。

https://stackoverflow.com/questions/52514840
复制相似问题