AngularJS中的动态模板如何转化为指令

4

我需要根据日期来确定模板。我看到了一个很好的例子。 但在那个例子中,模板非常简单,因此可以使用字符串。在我的情况下,我想使用php来生成模板,所以我这样使用它:

eng.directive('vis', function ($compile) {
var getTemplate = function(ir) {
    var k = (ir.visits.last && parseInt(ir.visits.last.done))?'V':'E';
    var s = (ir.data.kind == 0)?'H':'V';
    return s+k+'T';
}

var linker = function(scope, element, attrs) {
    scope.$watch('ir',function(){
        if (!scope.ir) return;
        element.html(jQuery('#'+getTemplate(scope.ir)).html()).show();
        $compile(element.contents())(scope);
    })
}
return {
    restrict: "E",
    rep1ace: true,
    link: linker
};});

模板如下:

<div id=HVT style="display:none">
    <p>horizontal view template</p>
</div>
<div id=HET style="display:none">
    <p>horizontal {{1+5}} Edit template</p>
</div>
<div id=VVT style="display:none">
    <p>vertical view template</p>
</div>
<div id=VET style="display:none">
    <p>vertical Edit template</p>
</div>

我确定有更聪明的方法。是否使用templateUrl更好?有人能告诉我如何在我的情况下使用它吗?

编辑:出了个问题。模板看不到scope。

3个回答

16

这也适用于在AngularJS中创建动态模板的情况:

在你的指令中使用:

template : '<div ng-include="getTemplateUrl()"></div>'

现在您的控制器可以决定使用哪个模板:

$scope.getTemplateUrl = function() {
  return '/template/angular/search';
};
因为你可以访问作用域参数,所以你也可以这样做:
$scope.getTemplateUrl = function() {
  return '/template/angular/search/' + $scope.query;
};

因此,您的服务器可以为您创建动态模板。


9
template和templateUrl可以采用函数形式,例如:function(el,attrs){ return '/tmpls/' + attrs.template; } - m.e.conroy
我尝试了上述方法,现在它对我来说运行良好,即使我控制导航,唯一的问题是如果我有动态状态(state('manualTest/:testName')并且回到动态状态页面,ng-init会被调用两次。 - Anand

3

我在这里找到了解决方案。

在这个例子http://jsbin.com/ebuhuv/7/edit中。

找到这段代码:

app.directive("pageComponent", function($compile) {
    var template_for = function(type) {
        return type+"\\.html";
    };
    return {
        restrict: "E",
        // transclude: true,
        scope: true,
        compile: function(element, attrs) {
            return function(scope, element, attrs) {
                var tmpl = template_for(scope.component.type);
                element.html($("#"+tmpl).html()).show();
                $compile(element.contents())(scope);
            };
        }
    };});

2

使用Angular,您不需要使用id。另外,您可以使用ng-show代替display:none

<div ng-show="HVT">
    <p>horizontal view template</p>
</div>
<div ng-show="HET">
    <p>horizontal {{1+5}} Edit template</p>
</div>
...

您的$watch回调函数(您可以在控制器或指令中定义)可以简单地修改适当的作用域属性:

var getTemplate = function (ir) {
    var k = (ir.visits.last && parseInt(ir.visits.last.done)) ? 'V' : 'E';
    var s = (ir.data.kind == 0) ? 'H' : 'V';
    return s + k + 'T';
}
$scope.$watch('ir', function () {
    if (!$scope.ir) return;
    // hide all, then show the one we want
    $scope.HVT = false;
    $scope.HET = false;
    $scope.VVT = false;
    $scope.VET = false;
    $scope[getTemplate($scope.ir)] = true;
})

Fiddle。该 fiddle 中有上述代码在控制器中,因为我不知道您可能在哪里使用该指令。该 fiddle 也只是硬编码了 "VET",因为我不知道 ir 的样子。


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