我希望能够从promise
加载指令的模板。例如加载角度指令模板异步
template: templateRepo.get('myTemplate')
templateRepo.get
返回一个承诺,即在解析时将模板的内容包含在字符串中。
任何想法?
我希望能够从promise
加载指令的模板。例如加载角度指令模板异步
template: templateRepo.get('myTemplate')
templateRepo.get
返回一个承诺,即在解析时将模板的内容包含在字符串中。
任何想法?
你可以加载指令中的HTML应用到你的元素和编译。
.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){
});
}
}
});
我会做的就是在我的指令添加一个ng-include选择性地加载什么,我需要
入住此演示从角页。它可以帮助:
这是一个非常有趣的问题,它带有不同复杂性的几个答案。正如其他人已经建议的那样,您可以将指令加载到指令中,并且在加载模板时将被替换。
看到,因为你想更通用的负荷指标的解决方案,应该适用于其他的事情,我建议:
这里是非常简单的例子,你可以开始:
<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"
}
};
});
在实时代码中,您必须将$timeout
替换为$http.get(templateUrl)
,我用前者来说明异步加载。
如何模板载入作品在我的例子:
$templateCache
模板。[$compile][2]
它。如果你不知道什么是$templateCache
,read the docs。 AngularJS默认使用templateUrl
,所以我也这样做了。
模板加载可能会移动到装饰器,但我缺乏相关经验。这将进一步分离担忧,因为指令不需要了解指示器,并摆脱了样板代码。
我也添加了ng-repeat
和run
东西来演示如果模板已经加载,它不触发指标。
````
/**
* 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;
}]);
````
请也描述你的答案,不只是发布一些代码。 –
嘿罗布任何机会,你可以解释为什么这种情况? – prasanthv