AngularJS - 指令中的不同模板

时间:2013-07-04 15:14:42

标签: angularjs angularjs-directive angularjs-ng-repeat

我有一个基于twitter bootstrap的表单,每个字段都有自己的配置

// controller (the template shows this in ng-repeat

$scope.fields = [{name:"f1", label:"Field 1", with_button: false},
                 {name:"f2", label:"Field 2", with_button: true}]

我正在尝试制作一个根据“field.with_button”自定义模板的“条件指令”

// Without button
<div class="controls">
    <input type="text" id="i_{{field.name}}">
</div>

// With button
<div class="controls">
    <div class="input-append">
        <input type="text" id="i_{{field.name}}">
        <span class="add-on">bt</span>
    </div>
</div>

我搜索了很多但没有找到任何解决方案,我试图只创建一个div并使用编译器函数将内容放入其中但它没有解析,如果我调用$apply它就会崩溃。 / p>

我该怎么做这个指令?

错误我的最后一次尝试:

angular.module('mymodule',[]).directive('ssField', function() {
    return {
        transclude:false,
        scope: {
            field: '='
        },
        restrict: 'E',
        replace:true,
        template: '<div class="controls">{{innerContent}}</div>',
        controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) {
            $scope.$eval('$scope.innerContent = \'<input type="text" id="input_{{field.name}}" placeholder="{{field.name}}" class="input-xlarge">\'');
        }]
    };
});

//<ss-field field="{{field}}"></ss-field>

3 个答案:

答案 0 :(得分:5)

您可以使用$http$compile服务来完成您的工作。

http://plnkr.co/edit/Xt9khe?p=preview

这个plnkr应该说明需要做什么,但基本上是:

  1. 根据条件使用$http加载模板。
  2. 使用$compile编译加载的模板与当前范围。
  3. angular.module('mymodule',[]).directive('ssField', ['$http', '$compile', function($http, $compile) {
        return {
            transclude:false,
            scope: {
                field: '='
            },
            restrict: 'E',
            replace:true,
            template: '<div class="controls"></div>',
            link: function(scope, element, attrs) {
              var template;
              var withButtonTmpl = 'with_button.html';
              var withoutButtonTmpl = 'without_button.html';
    
              if (scope.field.with_button) {
                $http.get(withButtonTmpl).then(function(tmpl) {
                  template = $compile(tmpl.data)(scope);
                  element.append(template);
                });
              } else {
                $http.get(withoutButtonTmpl).then(function(tmpl) {
                  template = $compile(tmpl.data)(scope);
                  element.append(template);
                });
              }
            }
        };
    }]);
    

    您可以将指令更改为更健壮,因此URL不会直接嵌入指令中以便重复使用等,但概念应该类似。

答案 1 :(得分:2)

为了进一步扩展Cuing Vo的答案,这与我的使用类似(不使用外部局部和额外的$ http调用):

http://jsfiddle.net/LvUdQ/

myApp.directive('myDirective',['$compile', function($compile) {
    return {
        restrict: 'E',

        template: '<hr/>',
        link: function (scope, element, attrs, ngModelCtrl) {
            var template = {
                'templ1':'<div>Template 1</div>',
                'templ2':'<div>Template 2</div>',
                'default':'<div>Template Default</div>'
            };
            var templateObj;
            if(attrs.templateName){
                templateObj = $compile(template[attrs.templateName])(scope);
            }else{
                templateObj = $compile(template['default'])(scope);
            }
            element.append(templateObj);
        }    
    };
}]);

然而,从表现的角度来看,我不太确定它的圣经。

答案 2 :(得分:1)

在AngularJS中,直接操作DOM必须只是最后的解决方案。在这里,您只需使用ngSwitch指令:

angular.module('mymodule',[]).directive('ssField', function() {
    return {
        transclude:false,
        scope: {
            field: '='
        },
        restrict: 'E',
        replace:true,
        template:
            '<div class="controls" data-ng-switch="field.with_button">' +
                '<input type="text" id="i_{{field.name}}" data-ng-switch-when="false">' +
                '<div class="input-append" data-ng-switch-default>' +
                    '<input type="text" id="i_{{field.name}}">' +
                    '<span class="add-on">bt</span>' +
                '</div>' +
            '</div>',
    };
});