Javascript 带有angularjs指令的动态标记

Javascript 带有angularjs指令的动态标记,javascript,json,angularjs,angularjs-directive,Javascript,Json,Angularjs,Angularjs Directive,我想在angularjs中创建一个元素指令,该指令从作为属性传递的json blob生成一个html元素。我已经尝试了以下的一些变体 demoApp.directive("element", function() { return { restrict: "E", scope: { attributes: "@", name: "@" }, template:

我想在angularjs中创建一个元素指令,该指令从作为属性传递的json blob生成一个html元素。我已经尝试了以下的一些变体

demoApp.directive("element", function() {
    return {
        restrict: "E",
        scope: {
            attributes: "@",
            name: "@"
        },
        template:         
            function(name, attributes) {
                var templateString = "<" + attributes.tag;
                for (attribute in attributes) {
                    if (attribute != "name_displayed" && attribute != "tag") {
                        templateString += " " + attribute + "=\"" attributes[attribute] + "\"";
                    }
                }
                templateString += " name=\"" field + "\"";
                templateString += ">";
                templateString += "</" + attributes.tag + ">";
                return attributes.name_displayed + ": " + templateString;
            }(name, attributes)
    };
});
一个名字看起来像

<div ng-repeat="(name, attributes) in fields">
    <element name="{[{name}]}" attributes="{[{attributes}]}"></element>
</div>
{"name_displayed":"Agency","size":"30","tag":"input","type":"text"}
agency

看起来我无法将函数用于模板,也无法访问属性或名称对象。

您可以在
链接
函数中实现逻辑,而不是
模板
。试试这个:

HTML

<element ng-repeat="field in fields" />

JavaScript

angular.module('demo', []).
    controller('demoCtrl', ['$scope', function($scope) {
      $scope.fields = [{
        "tag": "input",
        "type": "text",
        "value": "Demo app",
        "name": "my_input",
        "label": "My Text"
      }, {
        "tag": "input",
        "type": "checkbox",
        "checked": "checked",
        "name": "my_checkbox",
        "label": "My Checkbox"
      }, {
        "tag": "input",
        "type": "button",
        "value": "Click Me",
        "name": "my_button"
      }];
    }]).
    directive('element', function() {
      return {
        restrict: "E",
        replace: true,
        template: "<div></div>",
        link: function(scope, element, attrs) {
          var label,
              el,
              key,
              field;

          field = scope.field;

          if('label' in field) {
            label = document.createElement('label');
            label.innerHTML = field.label;
            element.append(label);
            element.append(document.createTextNode(': '));
          }

          el = document.createElement(field.tag);
          for(key in field) {
            if(field.hasOwnProperty(key) && // avoid prototype properties
                key !== 'tag' && // avoid tag
                key !== 'label' && // avoid label
                key[0] !== '$' // avoid angular staff derived from scope
            ) {
              el.setAttribute(key, field[key]);
            }
          }
          element.append(el);
        }
      };
    });
angular.module('demo',[])。
控制器('demoCtrl',['$scope',函数($scope){
$scope.fields=[{
“标记”:“输入”,
“类型”:“文本”,
“值”:“演示应用程序”,
“名称”:“我的输入”,
“标签”:“我的文本”
}, {
“标记”:“输入”,
“类型”:“复选框”,
“已检查”:“已检查”,
“名称”:“我的复选框”,
“标签”:“我的复选框”
}, {
“标记”:“输入”,
“类型”:“按钮”,
“值”:“单击我”,
“名称”:“我的按钮”
}];
}]).
指令('element',函数(){
返回{
限制:“E”,
替换:正确,
模板:“”,
链接:函数(范围、元素、属性){
var标签,
埃尔,
钥匙
领域
字段=scope.field;
if(字段中的“标签”){
label=document.createElement('label');
label.innerHTML=field.label;
元素。追加(标签);
元素.append(document.createTextNode(“:”);
}
el=document.createElement(field.tag);
用于(输入字段){
if(field.hasOwnProperty(key)&&&//避免原型属性
键!==“标记”&&&//避免标记
键!==“标签”&&&//避免标签
键[0]!='$'//避免从范围派生角度标尺
) {
el.setAttribute(键,字段[key]);
}
}
元素。追加(el);
}
};
});
下面是一个工作示例:

请查看以下内容:


它可以工作,但是对于您试图解决的问题,它是一种非常糟糕的方法。

您的json是第一个问题。将标记指令存储在json中(可能保存到服务器上)是很奇怪的……我很想说这很愚蠢。即使您需要能够接受一些用户输入并形成一个模板以供以后输出,您也可以将模板保存为html文件,而不是json。您有没有更好的方法的建议?
var app = angular.module('hmm', []);

function ctrl($scope) {
    $scope.fields = {
        first: '{"name_displayed": "Agency", "size": "30", "tag": "input", "type": "text"}',
        second: '{"name_displayed": "Foo", "size": "30", "tag": "input", "type": "password"}',
        third: '{"name_displayed": "Bar", "size": "30", "tag": "input", "type": "number"}'
    };
}

app.directive('blah', function() {

    var template = function(name, attributes) {
        var templateString = "<" + attributes.tag;
        for (var attribute in attributes) {
            if (attribute != "name_displayed" && attribute != "tag") {
                templateString += " " + attribute + '="' + attributes[attribute] + '"';
            }
        }
        templateString += ' name="' + name + '"';
        templateString += ">";
        templateString += "</" + attributes.tag + ">";
        return attributes.name_displayed + ": " + templateString;
    };

    return {
        restrict: "E",
        link: function(scope, element, attrs){
            var attributes = angular.fromJson(attrs.attributes);
            var tpl = template(attrs.name, attributes);
            element.html(tpl);
        }
    };

});
<div ng-app="hmm">
    <div ng-controller="ctrl">
        <div ng-repeat="(name, attributes) in fields">
            <blah name="{{name}}" attributes="{{attributes}}"></blah>
        </div>
    </div>    
</div>