【问题标题】:AngularJS: dynamic custom directive with multiple templatesAngularJS:具有多个模板的动态自定义指令
【发布时间】:2017-02-19 13:50:28
【问题描述】:

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

我的 JSON 结构如下:

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

我的目标是根据构造函数参数的“类型”显示特定的(例如数字、文本等)输入字段,并用“值”对其进行初始化。所以,如果第一个生成器被选中,我想要这样的东西:

<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) 我是否在自定义指令元素中正确传递了 param 对象?

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

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

4) 我可以为所有此类元素的 HTML 属性(如名称和值)使用前缀“ng-attr-”吗?

5) 我的模板代码与我粘贴的完全一致——我是否需要将其设为包含头部、主体等的有效 HTML 结构?我必须用 AngularJS 附加&lt;script&gt; 吗?我已经这样做了,但再一次,没有任何变化。

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

非常非常感谢您的意见! :)

【问题讨论】:

    标签: angularjs dynamic angularjs-directive angularjs-templates


    【解决方案1】:

    当您执行param : '@' 时,这是一个“文本绑定”。如果您想告诉 Angular 不要将绑定到属性的内容解释为作用域上的属性,而是直接解释为字符串,这很有用。

    如果你愿意的话

    &lt;my-custom-directive param="hello"&gt;&lt;/my-custom-directive&gt;

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

    在您的情况下,当您执行 param="{{param}}" 时,Angular 首先通过查看范围将“参数”解包为字符串文字,然后创建绑定。因此,即使param 是一个字符串,这可能会起作用,但在你的情况下,它是一个对象,所以我认为它不会很好地发挥作用。所以我会直接绑定到它(见下面我的最终代码)。

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

    app.directive("constructorParam", function() {
      return {
        scope: {
          param: '='
        },
        templateUrl: '/html_templates/constructor_param_template.html'
      };
    });
    <!-- 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>

    如果它仍然不起作用,请告诉我,以便我可以在 CodePen 中尝试。

    【讨论】:

      【解决方案2】:

      1) 不,您需要在将值传递给指令时删除大括号

      &lt;constructor-param param="param"&gt;&lt;/constructor-param&gt;

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

      scope: {
          param: '='
      },
      

      4) 如果您需要绑定数据,请使用ng-model 而不是ng-attr

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

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

      Demo

      【讨论】:

        【解决方案3】:

        首先,感谢你们两位的帮助!不幸的是,我无法将任何给定的答案标记为正确,因为我必须将它们混合才能得到我想要的。

        这里就不细说了,就和大家分享一下最终代码

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

        再次感谢您,如果没有您的帮助,我不会这么快解决这个问题!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-03-17
          • 1970-01-01
          • 2017-07-22
          • 2016-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-01
          相关资源
          最近更新 更多