2014-01-06 103 views
1

我正在尝试创建一个网页,其中一些元素(窗体和按钮)变得可见,或者在单击某些其他元素(按钮)时被隐藏。
我试图找到一种方法来管理这个问题,这是可重用的,并且易于维护。如何管理DOM元素依赖关系

我目前的解决方案如下所示,但我希望有人有一个更优雅的解决方案。
我自己的解决方案的问题是,当依赖关系数量增加时,读取会变得困难。当我添加另一个按钮和表单时,它还需要很多编辑。


我目前的解决方案是使用可观察到管理的形式状态,就像这样:

HTML:

<button id="button-A">Show form A, hide button A and B</button> 
    <button id="button-B">Show form B, hide button A and B</button> 
    <form id="form-A"> 
    ...this form is initially hidden 
    ...some form elements 
    <button id="cancel-A">Hide form A, show button A and B</button> 
    </form> 
    <form id="form-B"> 
    ...this form is initially hidden 
    ...some form elements 
    <button id="cancel-B">Hide form B, show button A and B</button> 
    </form> 

飞镖:

import 'dart:html'; 
    import 'package:observe/observe.dart'; 

    final $ = querySelector; 
    final $$ = querySelectorAll; 

    Map<String, bool> toBeObserved = { 
    "showFormA" : false, 
    "showFormB" : false 
    }; 

    // make an observable map 
    ObservableMap observeThis = toObservable(toBeObserved); 

    // start managing dependencies 
    main() { 
    // add click event to buttons 
    $('#button-A') 
    ..onClick.listen((E) => observeThis["showFormA"] = true); 
    $('#button-B') 
    ..onClick.listen((E) => observeThis["showFormB"] = true); 

    // add click events to form buttons 
    $('#cancel-A') 
    ..onClick.listen((E) { 
     E.preventDefault(); 
     E.stopPropagation(); 
     observeThis["showFormA"] = false; 
    }); 
    $('#cancel-B') 
    ..onClick.listen((E) { 
     E.preventDefault(); 
     E.stopPropagation(); 
     observeThis["showFormB"] = false; 
    }); 

    // listen for changes 
    observeThis.changes.listen((L) { 

     L.where((E) => E.key == 'showFormA').forEach((R) { 
     $('#form-A').style.display = (R.newValue) ? 'block' : 'none'; 
     $('#button-A').style.display = (R.newValue || observeThis['showFormB']) ? 'none' : 'inline-block'; 
     $('#button-B').style.display = (R.newValue || observeThis['showFormB']) ? 'none' : 'inline-block'; 
     }); 
     L.where((E) => E.key == 'showFormB').forEach((R) { 
     $('#form-B').style.display = (R.newValue) ? 'block' : 'none'; 
     $('#button-A').style.display = (R.newValue || observeThis['showFormA']) ? 'none' : 'inline-block'; 
     $('#button-B').style.display = (R.newValue || observeThis['showFormA']) ? 'none' : 'inline-block'; 
     }); 

    }); 
    } 

回答

1

你可以使用聚合物的模板功能,如

<template if="showA">... 

这应该不会将您的元素嵌入到聚合物元素中。
This discussion提供了一些信息如何使用<template>没有聚合物元素。 使用聚合物元素也可能有用。
这一切都取决于您的要求/偏好。

Angular.dart对于这种视图操作也很有用。

如果你想使用普通的Dart/HMTL,我不知道如何简化你的代码。

+0

您好,Günter,感谢您的建议。这在我看来就像迄今为止最通用的解决方案。当我有一段时间了,我会在将来看聚合物。 –

2

您可以使用这样的事情来处理一个通用的方法的所有元素:

final Iterable<ButtonElement> buttons = querySelectorAll('button') 
    .where((ButtonElement b) => b.id.startsWith('button-')); 

final Iterable<ButtonElement> cancels = querySelectorAll('button') 
    .where((ButtonElement b) => b.id.startsWith('cancel-')); 

final Iterable<FormElement> forms = querySelectorAll('form') 
    .where((FormElement b) => b.id.startsWith('form-')); 

buttons.forEach((b) { 
    b.onClick.listen((e) { 
    // name of clicked button 
    final name = b.id.substring(b.id.indexOf('-') + 1); 
    // hide all buttons 
    buttons.forEach((b) => b.hidden = true) 
    // show the good form 
    querySelector('#form-$name').hidden = false; 
    }); 
}); 

cancels.forEach((b) { 
    b.onClick.listen((e) { 
    // show all buttons 
    buttons.forEach((b) => b.hidden = false); 
    // hide all forms 
    forms.forEach((b) => b.hidden = true); 
    // prevent default 
    e.preventDefault(); 
    }); 
}); 

// hide all form at startup 
forms.forEach((f) => f.hidden = true); 
+0

嗨,亚历山大,那是一些美丽的代码。只要我添加表单和按钮来显示这些表单,这将工作。我希望在将来找到一些通用的解决方案,当逻辑改变时(如显示/隐藏多个表单,根据其他表单的可见性显示/隐藏表单中的字段),这些解决方案也可以工作。 –

4

您可以使用基本的CSS来显示/隐藏的元素。

HTML

<div id="container" class="show-buttons"> 
    <button id="button-A" class="btn" data-group="a">...</button> 
    <button id="button-B" class="btn" data-group="b">...</button> 
    <form id="form-A" class="form group-a">...</button> 
    <form id="form-B" class="form group-b">...</button> 
</div> 

CSS

.btn, .form { 
    display: none; 
} 

.show-buttons .btn, 
.show-a .form.group-a, 
.show-b .form.group-b { 
    display: block; 
} 

在DART刚刚拿到data-group(或者任何你想召本)从按钮属性。在container元素上切换CSS类(show-buttons,show-ashow-b)以在按钮和特定窗体之间切换。

该解决方案非常容易扩展。