gpt4 book ai didi

javascript - Ember - 嵌套递归模块

转载 作者:行者123 更新时间:2023-11-30 09:19:43 25 4
gpt4 key购买 nike

我正在研究点击和放置功能 --- 在页面上,模块以递归方式使用,因此它有一个父项和一个子项。

我遇到了一个问题,如果用户开始选择 child - 然后选择 parent - 我想取消选择 child 。尽管我不确定如何存储或监视所选父项/子项的更改以进行全局取消选择。

所以用户已经选择了 bacon3 的 child ..如果他们选择了 parent - 它需要取消选择 child - 但我觉得我目前被锁定在模块的范围内

enter image description here

最佳答案

我认为这个例子会对你有所帮助https://canary.ember-twiddle.com/468a737efbbf447966dd83ac734f62ad?openFiles=utils.tree-helpers.js%2C

所以,这是一个有趣的问题。事实证明,这更像是一个递归问题,而不是与 ember、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>

和递归助手(这是一团糟,但我只是在制作原型(prototype)):

// 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;
}

希望这对您有所帮助。

enter image description here

关于javascript - Ember - 嵌套递归模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52514840/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com