【问题标题】:How to have a directive having templateUrl as null or undefined or empty string如何让 templateUrl 为空或未定义或空字符串的指令
【发布时间】:2014-10-23 13:17:55
【问题描述】:

我正在尝试实现一个通用的下拉菜单指令。 我通常传递具有大模板的菜单的 templateUrl。 但是在“ul”标签中有像 3 个“li”这样的小菜单。 我不想为它们制作单独的模板以使用 templateUrl 调用,我只想使用实现指令的元素内部的 html 来实现功能。

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

        }
}

这就是我正在做的,但是因为它想要加载模板而出错。这附近有什么工作?

Aim = 如果作为 templateUrl 传递,则呈现模板,或者如果 templateUrl 未作为属性传递,则仅使用指令元素中的元素

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    我正在制作自己的框架,我遇到了和你一样的情况。 所以我写了一个执行动态模板url的模块。如果没有定义元素或默认templateUrl,它将元素的内部内容作为字符串存储在使用随机生成的密钥命名的$templateCache服务中,然后如果您将其动态设置为指令的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,由用户或包含原始内容的缓存中定义。

    如果我的英语不好,希望能帮上忙。

    【讨论】:

      【解决方案2】:

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

      在声明你的指令时你可以这样做:

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

      希望这会有所帮助。

      【讨论】:

        【解决方案3】:

        看起来这个站点提供了解决方案,你应该自己获取 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);
            }
        
        });
        

        【讨论】:

        • 这不是我真正想要的。如果我没有将 templateUrl 作为指令中的属性传递,我不应该尝试从 url 加载 html。
        • 可能只是检查属性是否未定义应该这样做
        • 大声笑是什么让你认为我没有那样做?这是用例:如果我将 url 作为 templateUrl 属性传递,则指令的 templateUrl 属性会从中获取 html 如果我不传递 url,它将获取未定义并给出错误。如果我没有传递 url,我希望指令不获取数据。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-25
        • 2021-07-04
        相关资源
        最近更新 更多