AngularJS: 具有多个模板的动态自定义指令
AngularJS: dynamic custom directive with multiple templates
我是一名 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",
}
]
}
]
我的目标是根据构造函数参数的 "type" 显示特定的(例如数字、文本等)输入字段,并使用 "value" 对其进行初始化。所以,如果选择了第一个生成器,我想要这样的东西:
<html>
<select>
<option selected="selected" value="true">Yes</option>
<option value="false">No</option>
</select>
<input type="number" value="2">
<html>
我已经阅读了一些线程并决定在我的 loop:
中使用自定义指令
<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) 我是否在自定义指令元素中正确传递了参数对象?
2) 我不确定指令的 scope
- 我也试过 param : '=param'
- 它也不起作用...
3) 我应该如何读取模板中传递的对象的属性?我试过:value="{{param.type}}"
、value={{param.type}}
和 ng-attr-value="{{param.value}}"
。 None 有效,但可能有完全不同的原因...
4) 我可以对所有此类元素的 HTML 属性使用前缀 "ng-attr-" 作为名称和值吗?
5) 我的模板代码正是我粘贴的代码 - 我是否需要使其成为具有头部、主体等的有效 HTML 结构?我必须附加 <script>
和 AngularJS 吗?我已经这样做了,但还是没有改变。
6) 整个故事的使用场景是从下拉列表中选择一个具体的生成器,并以指定的方式显示它的构造函数参数。因此它必须通过生成器的更改重新生成 HTML。我假设它是在 ng-repeat 循环中完成的,但请确认。
非常非常感谢您的投入! :)
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
当您执行 param : '@'
时,那就是 "text binding"。如果您想告诉 Angular 不要将绑定到属性的内容解释为作用域上的 属性 而是直接解释为字符串,这很有用。
所以如果你愿意
<my-custom-directive param="hello"></my-custom-directive>
然后在您的指令中,param
将等于字符串 "hello"
。如果您使用 two-way 绑定 param : '='
绑定到 param
,则 Angular 会在作用域上查找 hello
属性 而不是获取它作为字符串文字。
在您的情况下,当您执行 param="{{param}}"
时,Angular 首先通过查看作用域将 "param" 解包为字符串文字,然后创建绑定。因此,即使 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 中试试。
首先感谢两位大佬的帮助!不幸的是,我无法将任何给出的答案标记为正确,因为我必须将它们混合才能得到我要找的东西。
这里就不多说了,直接给大家分享一下最终代码:
<!-- 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'
};
});
再次 - 非常感谢你,没有你的帮助我不会这么快解决这个问题!
我是一名 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",
}
]
}
]
我的目标是根据构造函数参数的 "type" 显示特定的(例如数字、文本等)输入字段,并使用 "value" 对其进行初始化。所以,如果选择了第一个生成器,我想要这样的东西:
<html>
<select>
<option selected="selected" value="true">Yes</option>
<option value="false">No</option>
</select>
<input type="number" value="2">
<html>
我已经阅读了一些线程并决定在我的 loop:
中使用自定义指令<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) 我是否在自定义指令元素中正确传递了参数对象?
2) 我不确定指令的 scope
- 我也试过 param : '=param'
- 它也不起作用...
3) 我应该如何读取模板中传递的对象的属性?我试过:value="{{param.type}}"
、value={{param.type}}
和 ng-attr-value="{{param.value}}"
。 None 有效,但可能有完全不同的原因...
4) 我可以对所有此类元素的 HTML 属性使用前缀 "ng-attr-" 作为名称和值吗?
5) 我的模板代码正是我粘贴的代码 - 我是否需要使其成为具有头部、主体等的有效 HTML 结构?我必须附加 <script>
和 AngularJS 吗?我已经这样做了,但还是没有改变。
6) 整个故事的使用场景是从下拉列表中选择一个具体的生成器,并以指定的方式显示它的构造函数参数。因此它必须通过生成器的更改重新生成 HTML。我假设它是在 ng-repeat 循环中完成的,但请确认。
非常非常感谢您的投入! :)
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
当您执行 param : '@'
时,那就是 "text binding"。如果您想告诉 Angular 不要将绑定到属性的内容解释为作用域上的 属性 而是直接解释为字符串,这很有用。
所以如果你愿意
<my-custom-directive param="hello"></my-custom-directive>
然后在您的指令中,param
将等于字符串 "hello"
。如果您使用 two-way 绑定 param : '='
绑定到 param
,则 Angular 会在作用域上查找 hello
属性 而不是获取它作为字符串文字。
在您的情况下,当您执行 param="{{param}}"
时,Angular 首先通过查看作用域将 "param" 解包为字符串文字,然后创建绑定。因此,即使 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 中试试。
首先感谢两位大佬的帮助!不幸的是,我无法将任何给出的答案标记为正确,因为我必须将它们混合才能得到我要找的东西。
这里就不多说了,直接给大家分享一下最终代码:
<!-- 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'
};
});
再次 - 非常感谢你,没有你的帮助我不会这么快解决这个问题!