【问题标题】:Angular (semi) dynamic form generation角(半)动态表单生成
【发布时间】:2014-05-27 01:45:40
【问题描述】:

我正在尝试简化使用 AngularJS 生成表单的方式。

我的最终目标是能够写出类似的东西:

<form>
  <field-div label="Name">
    <field which="form.name"></field>
  </field-div>

  <field-div label="Language">
    <field which="form.language"></field>
  </field-div>
</form>

为此,我正在使用两个指令(fieldDivfield)和两个 JavaScript 对象:一个代表正在表单中编辑的数据,另一个代表表单定义(字段类型、字段选项...)。

查看此 JSFIDDLE 获取代码:http://jsfiddle.net/vincedo/9Uf6C/

在我的头撞到墙上几次之后,我想我成功了。主要困难是让 Angular 处理字符串——我从我的表单定义对象(例如"entity.name")获得——作为具有双向数据绑定的范围属性。

我还有两个问题:

  • 这是正确的方法吗?更具体地说,我的代码每个字段使用两个 scope.$watch,我担心它可能会影响性能。
  • 在我的表单中,为什么“语言”字段中没有选择“英语”?这一定是个愚蠢的错误:HTML 源代码使用 0、1、2... 作为 &lt;option&gt; 值,而我的代码使用字符串键,例如 enfr... $wrap 和 $parse 这么多小时,我没有看到。 :-)

谢谢!

【问题讨论】:

  • 您需要正确更新您的小提琴,您的链接会打开一个空的 Angular fiddle 模板。
  • @supermasher:感谢您指出这一点!这是我的第一个 jsFiddle,我认为它们会自动更新。它现在应该可以工作了。
  • 我有一个我认为更好的解决方案,但由于您的模型参考包含“实体”,因此我现在无法使其工作。您可以编辑此表单定义以仅返回(例如)“名称”吗?
  • @Galdo:对不起,我不明白你的意思。你想让我编辑 $scope.form 对象以便只保留“名称”键吗?
  • 在您的模型中,您有一个来自其他地方的表单定义。您可以编辑此架构还是必须适应它?为了使我的解决方案起作用,线模型:'entity.name',必须更改为模型:'name',

标签: angularjs angularjs-directive


【解决方案1】:

您可以使用 ng-switch 标签 (http://docs.angularjs.org/api/ng.directive:ngSwitch) 执行此操作。像这样。

<div class="control-group" ng-repeat="element in form">
  <label class="control-label">{{element.label}}</label>
  <div class="controls" ng-switch="element.widget">
    <input ng-switch-when="text" type="text" ng-model="entity[element.model]" ng-required="element.required" />
    <select ng-switch-when="select" ng-model="entity[element.model]" ng-required="element.required" ng-options="o.key as o.name for o in element.options"></select>
  </div>
</div>

这是我的解决方案的一个工作示例:

http://jsfiddle.net/Galdo/Sqsc7/17/

请注意,我在您的架构中将 entity.name 更改为 name。

使用此解决方案,您将避免使用任何指令。纯棱角!

【讨论】:

  • Galdo,感谢您抽出宝贵时间。很高兴您使用ngRepeat 来遍历字段;就我而言,这不起作用,因为我需要严格控制表单布局(例如,同一&lt;div&gt; 中的两个字段,能够手动将模板中的一些属性传递到给定字段)......至于@ 987654326@ 指令,我知道它但决定反对它,因为它感觉就像“模板中的逻辑”。此外,无论如何我都需要一些 JS 代码来实现表单行为(例如动态添加/删除字段),所以我不能没有指令或控制器。
  • 值得注意的是您使用的entity[key] 技巧。它可以避免我使用$watch() 手动实现双向数据绑定。再次感谢您的帮助!
【解决方案2】:

对于您的第二个问题(为什么使用 0、1、2、... 而不是 'en'、'fr' 等),您需要使用对象而不是数组来绑定到 @ 987654323@ 元素。我找到了答案in another question,但总之你的模型变成了{ 'en': 'English', 'fr': 'French', 'und':'Undefined'},你的模板的ng-options变成了ng-options="k as v for (k,v) in options"

我在这里更新了你的小提琴:http://jsfiddle.net/StevenLJackson1/9Uf6C/7/

我也对多个手表的性能感兴趣(即,你的第一个问题的答案),因为我在我当前的项目中做类似的事情。

【讨论】:

    【解决方案3】:

    我创建了一个简单的表单生成器应用程序,源代码:https://github.com/Selmanh/angularjs-form-builder

    您可以在这里在线查看:http://selmanh.github.io/angularjs-form-builder/

    我的解决方案和你的类似,但没有使用 watch。

    【讨论】:

    • 正确地意味着仅共享链接不是答案..您也必须解释它们..
    【解决方案4】:

    您也可以考虑看看这个,它基于简单的 json 定义创建动态角度形式:

    https://github.com/danhunsaker/angular-dynamic-forms

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-01
      • 2012-11-15
      • 1970-01-01
      • 2014-09-07
      • 2010-10-11
      • 2015-12-16
      • 2014-08-23
      相关资源
      最近更新 更多