Download Angular Async Directive Template

I want to download a directive template from promise. eg.

template: templateRepo.get('myTemplate')

templateRepo.get returns a promise that when resolving the contents of the template in a string.

Any ideas?

+4
source share
4 answers

You can load your html inside your directive, apply it to your element and compile.

.directive('myDirective', function ($compile) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            //Some arbitrary promise.
            fetchHtml()
             .then(function(result){
                 element.html(result);
                 $compile(element.contents())(scope); 
              }, function(error){

              });
        }
    }
});
+13
source

This is a really interesting question with several answers of varying complexity. As suggested by others, you can put a downloadable image inside the directive and when the template is loaded, it will be replaced.

Having seen that you need a more general loading indicator solution, which should be suitable for other purposes, I suggest:

  • .
  • , .

, :

<button ng-click="more()">more</button>
<div test="item" ng-repeat="item in items"></div>
.throbber {
    position: absolute;
    top: calc(50% - 16px);
    left: calc(50% - 16px);
}
angular
.module("app", [])
.run(function ($rootScope) {
    $rootScope.items = ["One", "Two"];
    $rootScope.more = function () {
        $rootScope.items.push(Math.random());
    };
})
.factory("throbber", function () {
    var visible = false;
    var throbber = document.createElement("img");
    throbber.src = "http://upload.wikimedia.org/wikipedia/en/2/29/Throbber-Loadinfo-292929-ffffff.gif";
    throbber.classList.add("throbber");
    function show () {
        document.body.appendChild(throbber);
    }
    function hide () {
        document.body.removeChild(throbber);
    }
    return {
        show: show,
        hide: hide
    };
})
.directive("test", function ($templateCache, $timeout, $compile, $q, throbber) {
    var template = "<div>{{text}}</div>";
    var templateUrl = "templateUrl";

    return {
        link: function (scope, el, attr) {
            var tmpl = $templateCache.get(templateUrl);

            if (!tmpl) {
                throbber.show();
                tmpl = $timeout(function () {
                    return template;
                }, 1000);
            }

            $q.when(tmpl).then(function (value) {
                $templateCache.put(templateUrl, value);
                el.html(value);
                $compile(el.contents())(scope);
                throbber.hide();
            });
        },
        scope: {
            text: "=test"
        }
    };
});

JSBin.

$timeout $http.get(templateUrl), , .

:

  • , $templateCache.
  • , URL- .
  • [$compile][2].
  • .

, $templateCache, . AngularJS templateUrl, .

, , , . , .

ng-repeat run, , , .

+2
````
/**
 * async load template 
 * eg : 
 * <div class="ui-header">
 *     {{data.name}}
 *     <ng-transclude></ng-transclude>
 * </div>
 */
Spa.Service.factory("RequireTpl", [
    '$q',
    '$templateCache',
    'DataRequest',
    'TplConfig',
 function(
    $q,
    $templateCache,
    DataRequest,
    TplConfig
) {
    function getTemplate(tplName) {
        var name = TplConfig[tplName];
        var tpl = "";
        if(!name) {
            return $q.reject(tpl);
        } else {
            tpl = $templateCache.get(name) || "";
        }
        if(!!tpl) {
            return $q.resolve(tpl);
        }
        //加载还ζœͺθŽ·εΎ—ηš„ζ¨‘ζΏ
        return new $q(function(resolve, reject) {
            DataRequest.get({
                url : "/template/",
                action : "components",
                responseType : "text",
                components : name
            }).success(function(tpl) {
                $templateCache.put(name, tpl);
                resolve(tpl);
            }).error(function() {
                reject(null);
            });
        });
    }
    return getTemplate;
}]);
/**
 * usage:
 * <component template="table" data="info">
 *     <span>{{info.name}}{{name}}</span>
 * </component>
 */
Spa.Directive.directive("component", [
    "$compile",
    "RequireTpl",
function(
    $compile,
    RequireTpl
) {
    var directive = {
        restrict : 'E',
        scope : {
            data : '='
        },
        transclude : true,
        link: function ($scope, element, attrs, $controller, $transclude) {
            var linkFn = $compile(element.contents());
            element.empty();
            var tpl = attrs.template || "";
            RequireTpl(tpl)
            .then(function(rs) {
                var tplElem = angular.element(rs);
                element.replaceWith(tplElem);
                $transclude(function(clone, transcludedScope) {
                    if(clone.length) {
                        tplElem.find("ng-transclude").replaceWith(clone);
                        linkFn($scope);
                    } else {
                        transcludedScope.$destroy()
                    }
                    $compile(tplElem.contents())($scope);
                }, null, "");
            })
            .catch(function() {
                element.remove();
                console.log("%c component tpl isn't exist : " + tpl, "color:red")
            });
        }
    };
    return directive;
}]);
````
-1

All Articles