问题描述
我有一个 JointJS 代码的 jsfiddle,它给了我我想要的:https://jsfiddle.net/RaymondMH/s46uyq8v/156/
但是,当我尝试在实际应用程序中使用此代码时,ElementView.extend()
调用中定义的任何函数都不会被调用,并且 Element 不会像我希望的那样创建。
这就是我将它放入代码中的方式:
import { Injectable } from '@angular/core';
import * as joint from '@clientio/rappid';
import * as _ from 'lodash';
import * as V from 'jquery';
@Injectable({
providedIn: 'root'
})
export class SchematicElementService {
private SystemElement: any;
constructor() {
}
public GetNodeElement(): { node: joint.dia.Element,embedId: number } {
let element: joint.dia.Element;
element = new this.SystemElement();
element
.prop('numberOfComponents',4)
.position(150,150);
return { node: element,embedId: null };
}
public InitializeDeFinitions() {
let componentOutlineRect = {
x: 0,y: 0,width: 215,height: 24,fill: '#fafafa',stroke: '#000000','stroke-width': '0.1'
}
let componentText = {
x: 0,fill: 'black','font-size': 13,'font-family': 'Arial','font-weight': 'normal'
}
let componentStatusText = {
x: 14,y: 18,'font-weight': '600',fill: 'green'
}
let componentIconRect = {
x: 34,y: 5,width: 16,height: 16,fill: '#565656'
}
this.SystemElement = joint.dia.Element.extend({
defaults: joint.util.defaultsDeep({
type: 'custom.Element',outlineColor: 'black',numberOfComponents: 1,size: {
width: 215,height: 24
},attrs: {
body: {
...componentOutlineRect,fill: '#bebebe'
},bodytitle: {
...componentText
},components: {
...componentOutlineRect,y: 24,}
}
}),markup: [
{ tagName: 'rect',selector: 'body' },{ tagName: 'text',selector: 'bodytitle' },{ tagName: 'rect',selector: 'components' },selector: 'componentStatus' },selector: 'componentIcons' },selector: 'text' }
]
});
this.SystemElement.ElementView = joint.dia.ElementView.extend(
{
events: {
'dblclick': 'onDblClick','click .components': 'onComponentClick'
},init: function () {
console.log('************* init() function called!');
var model = this.model;
this.listenTo(model,[
'change:fillColor','change:outlineColor',].join(' '),this.update);
this.listenTo(model,'change:numberOfComponents',this.render);
},render: function () {
console.log('**************** render function called!');
var markup = this.constructor.markup;
var body = this.vBody = markup.body.clone();
var bodyTitle = this.vBodyTitle = markup.bodytitle.clone().text('A - Static Structural');
var components = this.vComponents = [];
var componentStatus = this.vComponentStatus = [];
var componentIcons = this.vComponentIcons = [];
var componentLabels = this.vComponentLabels = [];
for (var i = 0,n = this.model.prop('numberOfComponents'); i < n; i++) {
components.push(markup.components.clone());
componentStatus.push(markup.componentStatus.clone().text('✓'));
componentIcons.push(markup.componentIcons.clone());
componentLabels.push(markup.text.clone().text('Component ' + (i + 1)));
}
this.vel.empty().append(
_.flatten([
body,components
])
);
this.translate();
this.update();
},update: function () {
this.updateBody();
this.updateComponents();
},updateBody: function () {
var model = this.model;
var bodyAttributes = {
...componentOutlineRect,fill: '#aaaaaa',};
this.vBody.attr(bodyAttributes);
var bodyTitle = this.vBodyTitle;
bodyTitle.attr({
...componentText,transform: 'translate(14,16)'
});
this.vel.append(bodyTitle);
},updateComponents: function () {
console.log('************** updateComponents called!');
var model = this.model;
var numberOfComponents = model.prop('numberOfComponents');
var vComponents = this.vComponents;
for (var i = 0; i < numberOfComponents; i++) {
vComponents[i].attr({
...componentOutlineRect,y: 24 * (i + 1),'data-index': i
});
}
var vComponentStatus = this.vComponentStatus;
for (var i = 0; i < numberOfComponents; i++) {
var vstatus = vComponentStatus[i];
var tx = 14;
var ty = 24 * (i + 1);
vstatus.attr({
...componentStatusText,transform: 'translate(' + tx + ',' + ty + ')'
});
this.vel.append(vstatus);
}
var vComponentIcons = this.vComponentIcons;
for (var i = 0; i < numberOfComponents; i++) {
var vIcon = vComponentIcons[i];
vIcon.attr({
...componentIconRect,x: 34,y: 24 * (i + 1) + 4
});
this.vel.append(vIcon);
}
var vComponentLabels = this.vComponentLabels;
for (var i = 0; i < numberOfComponents; i++) {
var vText = vComponentLabels[i];
var tx = 58;
var ty = 24 * (i + 2) - 8;
vText.attr({
...componentText,' + ty + ')'
});
this.vel.append(vText);
}
},onComponentClick: function (evt) {
var index = +V(evt.target).attr('data-index');
var model = this.model;
var numberOfComponents = model.prop('numberOfComponents');
var vComponents = this.vComponents;
for (var i = 0; i < numberOfComponents; i++) {
vComponents[i].attr({
fill: i === index ? '#dddddd' : "#fafafa"
});
}
},onDblClick: function () {
this.model.prop('faded',!this.model.prop('faded'));
}
});
// SEE COMMENTS BELOW REGARDING THIS COMMENTED CODE:
//},{
// markup: {
// body: V('rect').addClass('body'),// bodytitle: V('text').addClass('bodytitle'),// components: V('rect').addClass('components'),// componentStatus: V('text').addClass('componentStatus'),// componentIcons: V('rect').addClass('componentIcons'),// text: V('text').addClass('text')
// }
//});
}
}
元素初始化如下:
ngOnInit(): void {
this.schematicElementService.InitializeDeFinitions();
this.graph = new joint.dia.Graph();
this.paper = new joint.dia.Paper({
model: this.graph,cellViewNamespace: joint.shapes.basic,el: $('#paper'),width: 2400,height: 2400,origin: { x: 600,y: 600 },gridSize: 1,// interactive: { addLinkFromMagnet: false },linkPinning: false
});
}
元素被添加到图表中,如下所示:
let nodeData = this.schematicElementService.GetNodeElement();
this.graph.addCell(nodeData.node);
与 jsfiddle 不同的是,Markup 放置在 Element.extend()
函数中,而不是放置在 ElementView.extend()
中(如 ElementView.extend()
的注释代码所示)。>
如上实现,我看到了几个“框”,但由于未使用 ElementView 中的函数,它不会按照我的预期处理事情。 IE。没有文本也没有多个框,因为这些是在函数中处理的。
当我从 Element.extend()
中删除 标记 并将其放入 ElementView.extend()
(即取消注释上面的注释代码)时,在处理此问题时出现以下错误:
ERROR Error: dia.ElementView: markup required
at child.renderMarkup (rappid.js:19452)
at child.render (rappid.js:19483)
at child.protoProps.render (rappid.js:18246)
at child.confirmUpdate (rappid.js:19372)
at child.updateView (rappid.js:29615)
at child.updateViewsBatch (rappid.js:29812)
at child.updateViews (rappid.js:29668)
at child.requestViewUpdate (rappid.js:29539)
at child.renderView (rappid.js:30305)
at child.onCellAdded (rappid.js:29261)
我添加到函数中的 console.log()
调用都没有写入控制台,所以这些函数都没有被调用。在 Joint 数据结构中定义我的自定义元素,如在 joint.shapes.custom = {}
中没有任何区别。我在使用 JointJS 或 rappid 库时遇到了同样的问题。
有没有人看到我在这里做错了什么?我不知道如何进行这项工作。
预先感谢您提供的任何帮助。
解决方法
我不确定这是否适用于您的情况,但您可以尝试使用 elementView
选项指定在初始化论文时使用的视图:
this.paper = new joint.dia.Paper({
model: this.graph,cellViewNamespace: joint.shapes.basic,elementView: this.schematicElementService.ElementView,...
另外,我不确定元素视图是否应该是元素的子元素。 就我而言,我将元素视图放在一个单独的变量中。