如何将templateUrl作为null或undefined或空字符串的指令

时间:2014-10-23 13:17:56

标签: javascript angularjs angularjs-directive

我试图实现一个针对下拉菜单进行推广的指令。 我通常会传递具有大模板的菜单的templateUrl。 但是有一些小菜单,如3" li"(s)in" ul"标签。 我不想使用templateUrl创建一个单独的模板,我只想使用实现该指令的元素中的html实现该功能。

return {
        restrict : 'A',
        templateUrl: function(element,attrs){
            return (attrs.templateUrl)? attrs.templateUrl : null;
        },
        scope:"",
        link: function (scope, element, attrs) {

        }
}

这就是我正在做的事情,但因为想要加载模板而收到错误。这里的工作是什么?

目标=如果作为templateUrl传递,则渲染模板,或者只使用指令元素中的元素,如果templateUrl未作为属性传递

3 个答案:

答案 0 :(得分:1)

我制作了自己的框架,我遇到了和你一样的情况。 所以我写了一个执行动态模板网址的模块。如果没有定义元素或默认templateUrl,它会将元素的内部内容存储为以随机生成的密钥命名的$templateCache服务中的字符串,然后如果您将其动态设置为指令' s templateUrl属性,其元素的内容与您最初编写的内容相同。 我不知道这是否是一个完美的解决方案,但对我来说已足够了:

模块(对不起,我无法托管它,我工作的信息安全阻止所有)

(function(){
    var moduleName = "templateManager",
        serviceName = "TemplateManager",
        NAMES = {
            ATTR_NAME: "templateUrl",
            TEMPLATE: "templateUrl",
        };

    angular.module(moduleName, [])
    .provider(
        serviceName,
        function(){
            function randomSelector(){
                var str = ""; 
                for(var i = 0; i < 10; i++)
                    str += String.fromCharCode(Math.floor(Math.random() * (91-65) + 65));
                return str + "_" + String(Math.random().toFixed(5)).split(".")[1];
            }

            this.$get = ["$templateCache",function($templateCache){
                var serv = {};
                //Private
                function noTpl(contents){
                    var selector = randomSelector();
                    $templateCache.put(selector, contents);
                    return selector;
                }
                //Public
                serv[NAMES.TEMPLATE] = function(templateUrl){

                    return function(tElem, tAttrs){
                        var defaultTpl = angular.isDefined(templateUrl) ? (angular.isFunction(templateUrl) ? templateUrl.apply(this,arguments) : templateUrl) : undefined,
                            elementTpl = angular.isDefined(tAttrs[NAMES.ATTR_NAME]) ? tAttrs[NAMES.ATTR_NAME] : undefined;

                        return elementTpl || defaultTpl || noTpl(tElem.html());
                    }
                }
                return serv;
            }]
        }
    );
})();

用例

<script>
angular.module("test",["templateManager"])
.directive(
    "dynTpl",
    ["TemplateManager",function(TemplateManager){
        return {
            restrict: "E",
            templateUrl: TemplateManager.getTemplateUrl(
                function(tElem, tAttrs){ //only for testing
                    if(tAttrs.testTpl === "default")
                        return "http://www.w3schools.com/jquery/demo_test.asp";
                    return undefined; 
                }),
        }
    }]
)
</script>
<body ng-app="test">
<dyn-tpl><p>Content!!</p></dyn-tpl> <!-- Should show: Content!! -->
<dyn-tpl test-tpl="default"><p>Content!!</p></dyn-tpl> <!-- Should show: This is some text from an external ASP file. -->
<dyn-tpl template-url="http://www.w3schools.com/jquery/demo_test_post.asp"><p>Content!!</p></dyn-tpl> <!-- Should show: Dear . Hope you live well in . -->
</body>

如您所见,此模块始终使用默认情况下由用户或包含原始内容的缓存定义的templateUrl。

我希望如果我的英语不好,我会帮助和抱歉。

答案 1 :(得分:0)

看起来这个网站提供了解决方案,您应该自己获取html,然后使用$compile()函数: http://onehungrymind.com/angularjs-dynamic-templates/

app.directive('contentItem', function ($compile) {

    var linker = function(scope, element, attrs) {

        if (scope.contentTemplate !== undefined){
            element.html(getTemplate(scope.contentTemplate)).show();
        }
        $compile(element.contents())(scope);
    }

});

答案 2 :(得分:0)

使用templateCache和本地模板变量会有帮助吗? 当您声明templateURL时,在执行任何http请求之前使用$ templateCache 如果它什么都不返回,你可以设置一个空模板,或者其他什么。

在宣布您的指令时,您可以这样做:

angular.module('<yourmodule>').directive('<yourdirective',[$templateCache, function($templateCache){
   var myTemplate = $templateCache.get('anURL') || "";
   return {
      restrict: 'A',
      //other declarations
      template: myTemplate
   }
}]);

希望这有帮助。