【问题标题】:Dynamical view according to data根据数据动态查看
【发布时间】:2015-09-17 01:56:24
【问题描述】:

对于一个有多个属性的对象,比如一只鞋可能有不同的colorsize等。

现在当我们尝试展示鞋子,让客户可以选择不同的属性时,我们使用单选(最简单的):https://jsfiddle.net/mwqy6217/

但是如何根据数据使视图可用呢?

例如,当红鞋售罄时,red 收音机应该是不可选中的。不同的尺寸也是如此。

我们可以用这个数据结构来表示鞋子:{shoe:{name:'',available:['red','black','40','41']}}

但不同的属性之间可能有关系,例如,40 码的红色鞋子已经售罄,而 40 码的黑色鞋子则没有。 我认为这个数据结构:

{shoe:{name:'',available:{color:{red:[40,41,42]},black:[42,43]}}}

因为鞋子可能有其他属性,比如“重量”,一个属性可能有 10 多个选项。

那么如何在数据库中表示这种关系,让前端工程师可以读取来构建视图呢?

更新:

https://jsfiddle.net/xqtgqzt2/

查看现场演示,所有可用选项均预定义为:

var options= [
    ["A1","B1","C1","D1"],
    ["A1","B3","D2"],
    ["A2","B1","C3","D2"]
];

现在如何根据选项改变单选按钮的状态?比如勾选A1时,只能勾选(启用)B1 B3,勾选A1 B1时,只能勾选C1 D1。

【问题讨论】:

  • 使用你的选项数组,这意味着什么?例如:如果我选择选项 A1,我将只能选择 B1=>C1=>D1 或 B3=>D2 或其他?
  • 所以也是上一级的选择,会成为以后选择的过滤器,意思是如果选择了A1-B1,用户只能选择C1-D1,即使从B1也可以选择C3-D2被选中,它会在级别之间受到更多限制吗?

标签: javascript data-modeling


【解决方案1】:

要显示有关选项多维数组的单选按钮,您可以执行以下操作:

var options = [
    ["A1", "B1", "C1", "D1"],
    ["A1", "B3", "D2"],
    ["A2", "B1", "C3", "D2"]
];
var firstLevel = [];
var selectedList = [];
//Enable first options, disable the others
$("input[type=radio]").each(function (indexInput) {
    var that = this;
    that.disabled = true;
    $.each(options, function (index, value) {
        firstLevel.push(value[0]);
        if (value[0] == that.value) {
            that.disabled = false;
        }
    });
});
//on check radio, change states
$("input[type=radio]").on("click", function () {
    var thatClicked = this;
    if (firstLevel.indexOf(thatClicked.value) !== -1) {
        $('input[type=radio]').removeAttr('checked');
        $(thatClicked).prop('checked', true);
    }
    var possibleOptions = [];
    selectedList.push(thatClicked.value);
    $.each(options, function (index, value) {

        possibleOptions = possibleOptions.concat(value[0]);
        var posInArray = value.indexOf(thatClicked.value);
        if (posInArray !== -1 && typeof value[posInArray + 1] !== 'undefined') {
            //check previous options
            $.each(selectedList, function (indexSelectedList, valueSelectedList) {
                if (value.indexOf(valueSelectedList) !== -1) {
                    possibleOptions = possibleOptions.concat(value[posInArray + 1]);
                }
            });

        }
    });
    $("input[type=radio]").each(function (indexInput) {
        if (possibleOptions.indexOf(this.value) !== -1) {
            this.disabled = false;
        } else {
            this.disabled = true;
        }
    });
});
.section {
    padding: 10px;
    overflow: hidden;
}
label {
    float: left;
    width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
    <div class="section">
        <label>
            <input type="radio" value="A1" /> <span>A1</span>

        </label>
        <label>
            <input type="radio" value="A2" /> <span>A2</span>

        </label>
    </div>
    <div class="section">
        <label>
            <input type="radio" value="B1" /> <span>B1</span>

        </label>
        <label>
            <input type="radio" value="B2" /> <span>B2</span>

        </label>
        <label>
            <input type="radio" value="B3" /> <span>B3</span>

        </label>
    </div>
    <div class="section">
        <label>
            <input type="radio" value="C1" /> <span>C1</span>

        </label>
        <label>
            <input type="radio" value="C2" /> <span>C2</span>

        </label>
        <label>
            <input type="radio" value="C3" /> <span>C3</span>

        </label>
    </div>
    <div class="section">
        <label>
            <input type="radio" value="D1" /> <span>D1</span>

        </label>
        <label>
            <input type="radio" value="D2" /> <span>D2</span>

        </label>
    </div>
</div>
<div id="info">var options= [ ["A1","B1","C1","D1"], ["A1","B3","D2"], ["A2","B1","C3","D2"] ];</div>

【讨论】:

  • A1 和 A2 都应该是可检查的。
  • @hguser 你的意思是总是可以检查的?
  • 用户应该能够从一个选项切换到另一个选项。在您的示例中,一旦检查了 A1,除非刷新页面,否则我无法再次检查 A2
  • @hguser 更新了我的 aswer 以允许用户在第一级选项之间切换
  • var options = [ ["A1", "B1", "C1", "D1"], ["A1", "B3", "D2"], ["A2", "B1", "C3", "D2"], ["B1", "C3", "D2"] ]; 选项的顺序始终不完整。我尝试了以下选项,但出现了一些奇怪的行为。
【解决方案2】:

我会将我的数据设置为类似于您的第二个选项,但是因为他们首先要关心的是尺码(您无法更改鞋码),所以我会显示尺码的可用颜色,而不是一种颜色的可用尺寸。您首先要列出所有可用性,因为如果客户知道可能有 9 码绿色“快乐鞋”,他们可能会稍后回来购买。然后,您将遍历可用选项以更改该尺寸或颜色是否可用。

这是设置的数据:

var objShoes = [{
    name: 'Happy Shoe',
    sizes: [9,10,11,12,13],
    colours: ['red','blue','green'],
    available: [{
        size: 9,
        colours: ['red']
    },{
        size: 10,
        colours: ['red', 'blue']
    },{
        size: 11,
        colours: ['blue']
    },{
        size: 12,
        colours: ['red', 'blue']
    },{
        size: 13,
        colours: ['red']
    }]
}, {
    name: 'Scary Shoe',
    sizes: [8,9,10,11,12],
    colours: ['black','grey'],
    available: [{
        size: 8,
        colours: ['black']
    }]
}];

Here's an example of how that could work,尽管我使用选择框而不是单选按钮。它们更整洁:)。

【讨论】:

  • color 和 size 只是我用的两个属性,其实有 5+ color-size 类似的属性。
【解决方案3】:

恕我直言,更简单的方法是将数据本身与属性的定义分开,并且属性之间没有层次结构。为此,您需要每个属性值都有一个唯一的 ID。

在此示例中,我使用数组中每个属性的索引作为 id 从availability 对象中引用它。

{
    attributes: [
        {value: "red",   type: "colour"}, // 0
        {value: "green", type: "colour"}, // 1
        {value: "black", type: "colour"}, // 2
        {value: "brown", type: "colour"}, // 3

        {value: 40, type: "size"}, // 4
        {value: 41, type: "size"}, // 5
        {value: 42, type: "size"}, // 6
        {value: 43, type: "size"}, // 7
        {value: 44, type: "size"}, // 8

        {value: true,  type: "with_shoelace"}, // 9
        {value: false, type: "with_shoelace"}, // 10
    ],

    products: [
        {
            name: 'some random shoe',
            availability: {
                0: [4, 7, 8, 9], // red is compatible with 40, 43 and 44, only with shoelace
                1: [4, 5, 9, 10], // green is compatible with 40, 43 and 44, with or without shoelace
                ...
                6: [2, 3, 9, 10], // 42 can be black or brown, with or without shoelace
                7: [0, 1, 10], // 43 can be red or green, without shoelace
                ...
                10: [1, 4, 6, 7, 8], // ...
            }
        },
        {
            name: 'another shoe',
            availability: {
                ...
            }
        }
    ]
}

在 GUI 上,您必须将每个选中的属性中的 availability 数组相交,以确定哪个选项可用。

【讨论】:

    猜你喜欢
    • 2018-09-18
    • 2015-03-18
    • 2016-04-21
    • 2018-06-11
    • 1970-01-01
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多