AngularJS指令:如何通过动态ID查找元素并修改模板

3
我将尝试根据一个包含动态属性的模板动态生成一个表单。我已经接近成功,但是在检索容器元素时遇到了一些问题。这是指令:
myApp.directive('myDirective', function () {
    return {
    template: "<div> <label>{{Field.Name}} <div id='{{Field.Name}}_Container'></div> </label></div>",
    replace: true,
    restrict: 'AE',
    scope: {
        Field: "=fieldInfo",
        FieldData:"="
    },
    link: function (scope, element, attr) {
        var input = "<input type='" + scope.Field.Type + "' data-ng-model='FieldData[" + scope.Field.Name + "]' />";
        var inputEl = angular.element(input);
        var container = angular.element("#" + scope.Field.Name + "_Container"); // Doesn't work
        container.append(inputEl);
    }
}

});

控制器:

function MyCtrl($scope) {
    $scope.Fields = [
      { Name: "field1", Type: "text", Data:null },
      { Name: "field2", Type: "number", Data:null }
    ];

     $scope.FieldData = {}; //{fieldname: fielddata}
}

Html:

<div ng-controller="MyCtrl">
      <my-directive data-ng-repeat="field in Fields" data-field-info="field">
    </my-directive>
</div>

基本上我有字段描述对象,需要根据它生成一个表单。我不太确定如何引用容器对象 - 是否需要在链接之前编译模板?此外,我实际上正在使用templateUrl,如果这很重要的话。这里还有一个fiddle
1个回答

5

你需要使用$compile将模板编译成html。此外,在链接函数中,可以使用element访问模板中的外部div

var myApp = angular.module('myApp', []);

myApp.directive('myDirective', function ($compile) {
    return {
        template: "<div> <label>{{Field.Name}} <div id='{{Field.Name}}_Container'></div> </label></div>",
        replace: true,
        restrict: 'AE',
        scope: {
            Field: "=fieldInfo",
            FieldData:"="
        },
        link: function (scope, element, attr) {
            var input = "<input type='" + scope.Field.Type + "' data-ng-model='FieldData[" + scope.Field.Name + "]' />";
            var html = $compile(input)(scope);
            element.find('div').append(html);
        }
    }
});

请查看jsfiddle


+1 但是未来的读者应该注意,element.find() 是递归的,所以如果模板比这个更复杂,你需要使用另一种方法(比如 element.children())。 - Josh David Miller
更改了它。重点是在链接函数中使用“element”。 - asgoth
我认为在这种情况下你的第一种方式是最好的。顺便说一句:我不认为 jqLite 支持像 jQuery 一样在 element.children 中搜索值,但我可能错了。 - Josh David Miller
有什么办法可以通过ID获取该容器div吗?我尝试编译元素,但没有成功:var container = $compile(elem)(scope); var el = angular.element("#" + scope.Field.Name + "_Container", container); - Evgeni
1
不行,不起作用。元素的id还没有编译好。如果我调用--> var a = $compile(elem)(scope);console.log(a.html());--由于某种原因它会返回null。在这种情况下并不是问题,但对于更复杂的模板,能够定位特定的元素会很好。 - Evgeni
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接