我需要使用Angular标记来生成Angular 评估/解析 HTML元素,这些标记由treant-js 动态添加到DOM。
我已经按照提议的解决方案there(涉及动态模块/组件创建)。但是,此实现存在越来越多的问题。
首先,我向子组件注入为父模块(Router,ActivatedRoute等)声明的所需依赖项:
this.addComponent(
this.treeContainer.nativeElement.outerHTML,
{},
this.conversation.threads,
this.route,
this.router,
this.ws
);
这对我来说似乎不对,因为最合乎逻辑的方法是将这些依赖项直接注入动态组件(动态模块中的导入),但我无法做到这一点。
另外,因为treant-js需要直接附加到DOM 它创建的新HTML组件(我想是为了正确绑定事件),我无法检索在它之前的HTML字符串在DOM中。所以,我发现丑陋的修复是:
this.treeContainer.nativeElement.outerHTML
提取HTML字符串(请参阅上面的代码段),然后将其作为动态组件的模板参数发送; $(this.treeContainer.nativeElement).remove();
。除了前面提到的问题,我尝试的解决方案根本不可接受。似乎treant-js 需要将其HTML元素附加到DOM以进行事件绑定和树存储/管理,因此当我复制树的HTML字符串以形成动态组件的模板时,第二棵树很好地被Angular评估,但不再受treant-js框架的影响(例如:某些功能,如可折叠句柄将不再有效)。
总结一下:我无法让Angular和treant-j同时处理我的树标记。
此外,我用来避免重复树的丑陋技巧会导致其他问题,无论是来自动态更新(用户交互创建的新节点),还是导航到多次翻页(路由)。
最后但并非最不重要,我甚至无法使用来自导入模块的ngModel
之类的Angular标记(例如FormsModule):我收到错误{{1没有绑定到输入元素。该模块当然是在我的父组件中导入的,我也尝试在动态模块中导入它:
ngModel
除非我很快找到让Angular和treant-js顺利合作的方法,否则我可能需要使用其他库,例如angular-tree-component或ng2-tree。最大的缺点是我可能会错过一些视觉功能(比如树的方向)和我发现很容易用treant-js实现的交互性。
我是Angular2的新手,所以我确实无法理解这些概念。我在我自己的Angular2项目中使用了treant-js,并且我坚持使用treant-js使Angular2 评估/编译生成的HTML中的指令。
我已经看到了这个:Integrating Treant-js in Angular2 Project将treant-js集成到项目中,但我只能使用一些静态HTML而不是private addComponent(template: string, properties: any = {}, threads: Thread[],
route: ActivatedRoute, router: Router, ws: WebSocketService) {
@Component({template})
class TemplateComponent implements OnInit {
//...
@NgModule({
declarations: [TemplateComponent],
imports: [FormsModule]
})
class TemplateModule {}
const module = this.compiler.compileModuleAndAllComponentsSync(TemplateModule);
const factory = module.componentFactories.find(componentFactory =>
componentFactory.componentType === TemplateComponent
);
const component = this.container.createComponent(factory);
Object.assign(component.instance, properties);
。
我在我的组件routerLink, ngIf or ngFor
中调用buildConversationTree:
ngInit
基本上,buildConversationTree() {
const config = {
container: '#tree',
connectors: {
type: 'step'
},
node: {
HTMLclass: 'thread-node',
collapsable: true
},
levelSeparation: 45
};
let treeConfig = this.buildNodes(this.conversation.threads);
treeConfig.unshift(config);
const tree = new Treant(treeConfig, this.onTreeLoaded, $);
}
方法通过调用buildNodes
方法为树的每个节点生成HTML:
nodeHTML
我的组件有一个简单的模板:
nodeHTML(data) {
return `
<div id="thread${data.id}" class="thread-node-wrapper">
<a class="main-link" routerLink="../thread/${data.id}">
Lorem ipsum
</a>
</div>
`;
}
在树生成之后变为:
<div class="tree-container">
<div id="tree"></div>
</div>
<div class="tree-container">
<div id="tree" class=" Treant Treant-loaded"><svg height="598" version="1.1" width="633" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="overflow: hidden; position: relative;"><desc style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Created with Raphaël 2.1.4</desc><defs style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></defs></svg><div class="node thread-node" style="left: 191.5px; top: 224px;">
<div id="thread60" class="thread-node-wrapper">
<a class="main-link" routerlink="../thread/60">
Lorem ipsum
</a>
</div>
</div></div>
</div>
仍未被Angular编译/识别。
在Angular.js中:
回到Angular.js(之前用于项目),我们将使用routerlink="../thread/60"
来解决问题:
$compile
以及ng-click,ng-show等所有指令都得到了解决,所以我对在Angular2中工作有多困难感到有些困惑。
我尝试了什么:
var treeIsLoaded = function () {
// ...
var e = $('#tree')[0];
$compile(e)($scope);
if (!$scope.$$phase) {
$rootScope.safeApply();
}
// ...
};
成员的命名模板中,但它可以正常工作。