AngularJS:具有多个模板的动态自定义指令

时间:2017-02-19 13:50:28

标签: angularjs dynamic angularjs-directive angularjs-templates

我是一名从事侧项目的Java开发人员。我决定使用AngularJS来使用我的RESTful Web服务。

我的 JSON结构如下:

[
  {
    "generatorName": "name1",
    "constructorParams": [
      {
        "type": "Boolean",
        "value": "true",
      },
      {
        "type": "Integer",
        "value": "2",
      }
    ]
  },
  {
    "generatorName": "name2",
    "constructorParams": [
      {
        "type": "Integer",
        "value": "10",
      },
      {
        "type": "Integer",
        "value": "10",
      }
    ]
  }
]

我的目标是根据"类型"显示特定的(例如编号,文本等)输入字段。构造函数参数param并用"值"初始化它。因此,如果选择了第一台发电机,我希望有这样的东西:

<html>
    <select>
        <option selected="selected" value="true">Yes</option>
        <option value="false">No</option>
    </select>

    <input type="number" value="2">
<html>

我已经阅读了一些帖子并决定在我的循环中使用自定义指令

<p ng-repeat="param in selectedGenerator.constructorParams">
      <constructor-param param="{{param}}"></constructor-param>
</p>

这是自定义指令

app.directive("constructorParam", function() {
    return {
        scope : {
            param : '@'
        },
        templateUrl : '/html_templates/constructor_param_template.html'
    };
});

此处模板

<div ng-switch="{{param.type}}">
    <div ng-switch-when="Integer">
        <input type="number" ng-attr-name="{{param.type}}" min="0" ng-attr-value="{{param.value}}">
    </div>

    <div ng-switch-when="Boolean">
        <select ng-if="{{param.value}}" ng-attr-name="{{param.type}}">
            <option selected="selected" value="true">Yes</option>
            <option value="false">No</option>
        </select>

        <select ng-if="!{{param.value}}" ng-attr-name="{{param.type}}">
            <option value="true">Yes</option>
            <option selected="selected" value="false">No</option>
        </select>
    </div>

    <div ng-switch-when="String">
        <input type="text" ng-attr-name="{{param.type}}" ng-attr-value="{{param.value}}">
    </div>

    <div ng-switch-when="Double">
        <input type="number" ng-attr-name="{{param.type}}" step="0.01" min="0" ng-attr-value="{{param.value}}">
    </div>
</div>

这些都不起作用。我可以在Chrome开发人员的工具中看到该指令运行,但它没有提供任何可见的输出。我的问题是:

1)我是否在custom指令元素中正确传递了param对象?

2)我不确定该指令的scope - 我还试过param : '=param' - 它也不起作用......

3)我应该如何阅读模板中传递的对象的属性?我尝试过:value="{{param.type}}"value={{param.type}}ng-attr-value="{{param.value}}"。没有用,但原因可能完全不同......

4)我可以使用前缀&#34; ng-attr - &#34;对于所有这些元素的HTML属性,如名称和值?

5)我的模板代码正是我所粘贴的 - 我是否需要将其设置为有头部,正文等的有效HTML结构?我是否必须将<script>与AngularJS联系起来?我已经做到了,但再一次,没有改变。

6)整个故事的使用场景是从下拉列表中选择一个具体的生成器,并以指定的方式显示它的构造函数参数。所以它必须通过生成器的更改来重新生成HTML。我认为它是在ng-repeat循环中完成的,但请确认一下。

非常感谢您的投入! :)

3 个答案:

答案 0 :(得分:2)

当您执行param : '@'&#34;文本绑定&#34;时。如果您想告诉Angular不要将您的属性绑定到作为范围属性的属性而是直接作为字符串,那么这非常有用。

所以如果你做

<my-custom-directive param="hello"></my-custom-directive>

然后在你的指令中,param将等于字符串"hello"。如果使用双向绑定param绑定到param : '=',则Angular将在范围内查找hello属性,而不是将其作为字符串文字。

在你的情况下,当你做param="{{param}}" Angular首先打开包装&#34; param&#34;通过查看范围,到字符串文字,然后它创建绑定。所以尽管如果param是一个字符串,这可能有效,但在你的情况下它是一个对象,所以我认为它不会很好。所以我会直接绑定它(参见下面的最终代码)。

在你的指令模板中,你还使用了一些期望范围绑定的Angular指令,所以我会尝试在没有大括号的情况下进行绑定。请参阅下面的示例代码。

&#13;
&#13;
app.directive("constructorParam", function() {
  return {
    scope: {
      param: '='
    },
    templateUrl: '/html_templates/constructor_param_template.html'
  };
});
&#13;
<!-- container -->
<p ng-repeat="param in selectedGenerator.constructorParams">
  <constructor-param param="{{param}}"></constructor-param>
</p>

<!-- TEMPLATE -->

<div ng-switch="param.type">
  <div ng-switch-when="Integer">
    <input type="number" ng-attr-name="param.type" min="0" ng-attr-value="param.value">
  </div>

  <div ng-switch-when="Boolean">
    <select ng-if="param.value" ng-attr-name="param.type">
            <option selected="selected" value="true">Yes</option>
            <option value="false">No</option>
        </select>

    <select ng-if="!param.value" ng-attr-name="param.type">
            <option value="true">Yes</option>
            <option selected="selected" value="false">No</option>
        </select>
  </div>

  <div ng-switch-when="String">
    <input type="text" ng-attr-name="param.type" ng-attr-value="param.value">
  </div>

  <div ng-switch-when="Double">
    <input type="number" ng-attr-name="param.type" step="0.01" min="0" ng-attr-value="param.value">
  </div>
</div>
&#13;
&#13;
&#13;

如果它仍然无效,请告诉我,以便我可以在CodePen中尝试。

答案 1 :(得分:1)

1)不,在将值传递给指令

时,需要删除大括号

<constructor-param param="param"></constructor-param>

2,3)在指令中使用=而不是@。因为@取参数的字符串值,=取参数值

scope: {
    param: '='
},

4)如果您需要绑定数据,请使用ng-model代替ng-attr

5)您不需要在constructor_param_template.html模板中添加html或body标签。

6)ng-repeat就是这么做的。一旦数组得到更新,它将动态更新DOM

Demo

答案 2 :(得分:0)

首先,谢谢你们俩的帮助!不幸的是,我无法将任何给定的答案标记为正确,因为我必须将它们混合以获得我想要的内容。

我在此不再赘述,让我与您分享最终代码

<!-- container -->
<p ng-repeat="param in selectedGenerator.constructorParams">
  <constructor-param param="param"></constructor-param>
</p>

<!-- template -->
<div ng-switch="param.type">
    <div ng-switch-when="Integer">
        <input type="number" name={{param.type}} min="0" value={{param.value}}>
    </div>

    <div ng-switch-when="Boolean">
        <select ng-if="param.value" name={{param.type}}>
            <option selected="selected" value="true">Yes</option>
            <option value="false">No</option>
        </select>

        <select ng-if="!param.value" name={{param.type}}>
            <option value="true">Yes</option>
            <option selected="selected" value="false">No</option>
        </select>
    </div>

    <div ng-switch-when="String">
        <input type="text" name={{param.type}} value={{param.value}}>
    </div>

    <div ng-switch-when="Double">
        <input type="number" name={{param.type}} step="0.01" min="0" value={{param.value}}>
    </div>
</div>

这是指令,你们两个都做对了:

app.directive("constructorParam", function() {
  return {
    scope: {
      param: '='
    },
    templateUrl: '/html_templates/constructor_param_template.html'
  };
});

再一次 - 非常感谢,如果没有你的帮助,我不会这么快就解决这个问题!