一个想法是使用 DOM 操作,这不是最推荐的 Angular 方式,但我知道了 working on this plunker. 和 second one with custom directive and randomized data to simulate your compiled avatar.
为了模拟您的异步调用,我使用了 ngResource。我的渲染函数返回一个带有特殊类标记compiledavatar 的字符串"<div class='compiledavatar'>Temporary Avatar</div>"。在一两秒钟内,您将在选择元素时看到临时头像。当 ngResource 调用完成时,我会查找类为 compiledavatar 的元素,然后将 html 替换为我下载的内容。完整代码如下:
var app = angular.module('plunker', ['selectize', 'ngResource']);
app.controller('MainCtrl', function($scope, $resource, $document) {
var vm = this;
vm.name = 'World';
vm.$resource = $resource;
vm.myModel = 1;
vm.$document = $document;
vm.myOptions = [{
id: 1,
title: 'Spectrometer'
}, {
id: 2,
title: 'Star Chart'
}, {
id: 3,
title: 'Laser Pointer'
}];
vm.myConfig = {
create: true,
valueField: 'id',
labelField: 'title',
delimiter: '|',
placeholder: 'Pick something',
onInitialize: function(selectize) {
// receives the selectize object as an argument
},
render: {
item: function(item, escape) {
var label = item.title;
var caption = item.id;
var Stub = vm.$resource('mydata', {});
// This simulates your asynchronous call
Stub.get().$promise.then(function(s) {
var result = document.getElementsByClassName("compiledavatar")
angular.element(result).html(s.compiledAvatar);
// Once the work is done, remove the class so next time this element wont be changed
// Remove class
var elems = document.querySelectorAll(".compiledavatar");
[].forEach.call(elems, function(el) {
el.className = el.className.replace(/compiledavatar/, "");
});
});
return "<div class='compiledavatar'>Temporary Avatar</div>"
}
},
// maxItems: 1
};
});
为了模拟 JSON API,我刚刚在 plunker mydata 中创建了一个文件:
{
"compiledAvatar": "<div><span style='display: block; color: black; font-size: 14px;'>an avatar</span></div>"
}
当然,你编译的函数应该在每次调用时返回不同的东西。我它给了我同样的证明原理。
此外,如果您的动态代码是 Agular 指令,这里有一个 second plunker 带有自定义指令和随机数据,以便您更好地查看解决方案:
数据包含自定义指令my-customer:
[{
"compiledAvatar": "<div><span style='display: block; color: black; font-size: 14px;'>an avatar #1 <my-customer></my-customer></span></div>"
},
{
"compiledAvatar": "<div><span style='display: block; color: black; font-size: 14px;'>an avatar #2 <my-customer></my-customer></span></div>"
},
(...)
指令定义为:
app.directive('myCustomer', function() {
return {
template: '<div>and a custom directive</div>'
};
});
该应用程序的主要区别在于您必须在替换 HTML 时添加 $compile 并且文本应显示 An avatar #(number) and a custom directive。我得到一个 json 值数组并使用一个简单的随机数来选择一个值。替换 HTML 后,我会删除该类,因此下次只会更改最后添加的元素。
Stub.query().$promise.then(function(s) {
var index = Math.floor(Math.random() * 10);
var result = document.getElementsByClassName("compiledavatar")
angular.element(result).html($compile(s[index].compiledAvatar)($scope));
// Remove class
var elems = document.querySelectorAll(".compiledavatar");
[].forEach.call(elems, function(el) {
el.className = el.className.replace(/compiledavatar/, "");
});
});
另外,我查看了 selectize 库,你不能返回一个承诺......因为它对渲染返回的值执行 html.replace。这就是为什么我去了一个临时字符串的路线,以便稍后检索和更新。
让我知道这是否有帮助。