如何管理DOM元素依赖项

时间:2014-01-06 00:36:35

标签: dom dependencies dart dart-html

我正在尝试创建一个网页,其中一些元素(表单和按钮)变得可见或在单击其他元素(按钮)时被隐藏。
我试图找到一种方法来管理它,它是可重用的,易于维护。

我目前的解决方案如下所示,但我希望有人能提供更优雅的解决方案 我自己的解决方案的问题是,当依赖项的数量增加时,它将变得难以阅读。当我添加另一个按钮和表单时,它还需要进行大量编辑。


我目前的解决方案是使用observable来管理表单的状态,如下所示:

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';
      });

    });
  }

3 个答案:

答案 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(或您想要调用的任何内容)属性。在show-buttons元素上切换CSS类(show-ashow-bcontainer)以在按钮和特定表单之间切换。

此解决方案很容易扩展。

答案 1 :(得分: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);

答案 2 :(得分:1)

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

<template if="showA">...

这也可以在不将元素嵌入Polymer元素的情况下工作 This discussion提供了一些如何在没有Polymer元素的情况下使用<template>的信息。 使用聚合物元素也很有用 这一切都取决于您的要求/偏好。

Angular.dart对于此类视图操作也很有用。

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