- Imports
- Directives
- jsplumb-toolkit
- jsplumb-miniview
- jsplumb-palette
- Rendering Nodes
- jsPlumb Service
- Limitations
Angular 1.x Integration
The jsPlumb Toolkit offers several components to assist you in integrating with Angular 1.x. The Toolkit uses "strict" format in all of its Angular components. For Angular 10/9/8/7/6/5/4/2 integration, refer to this page.
The Toolkit's Angular 1.x components are stored in a separate file - jsplumbtoolkit-angular-1.x.js
. You need to import this file, after you import the Toolkit.
The Angular components are stored inside a module called $jsPlumb
:
This directive creates a Toolkit instance and renders it to the given element.
<jsplumb-toolkit surface-id="mySurface" jtk-id="myToolkit" params="ToolkitParams" renderParams="RenderParams">
You can put content in here.
</jsplumb-toolkit>
Attributes
jtk-id Identifier for the Toolkit. Strictly speaking this is not required, but if you need to access the Toolkit via the
jsPlumbService
you will need to have set this.[surface-id] Provides the identifier to associate with the created Surface widget. This is optional, but you will need to provide this if you wish to attach a
jsplumb-miniview
orjsplumb-palette
.[params] Optional reference to parameters for the Toolkit constructor. By "reference" we mean the name of some variable that is in the scope in which the directive is executing.
[renderParams] Optional reference to parameters for the render call. By "reference" we mean the name of some variable that is in the scope in which the directive is executing.
[init] Optional reference to a function that will be called once the Toolkit and Surface have both been instantiated. The function's method signature is:
- [data] Optional reference to some Object in scope that contains the data for the Toolkit to load.
jsplumb-miniview
Creates a Miniview:
Attributes
- surface-id The ID of the Surface widget to which this Miniview should attach itself. Required.
Note When using the jsplumb-toolkit
Angular directive you must use the jsplumb-miniview
directive to configure a Miniview. Any miniview
declared in the renderParams
will be ignored.
jsplumb-palette
This directive is declared as both an Attribute and Element directive. Here it is used as an Attribute directive:
<div class="someClass" jsplumb-palette selector="li" generator="SomeController.dataGenerator">
<ul>
<li data-type="foo">FOO</li>
<li data-type="bar">BAR</li>
</ul>
</div>
Attributes
- jsplumb-palette This is what turns the directive on for the element.
- selector A CSS3 selector identifying which child elements should be draggable/droppable.
- generator The name of a function that is in scope that will be used to generate a dataset for a node that is being dragged.
In the example markup above, a suitable generator
function (here declared on SomeController
) might be:
When using the Angular integration you do not need to use Angular to render your nodes if you do not want to - you can use the standard Toolkit templating mechanism. If you wish to use Angular, though, you will need to create a directive for each Node type, and you'll need to use the jsPlumbFactory
to do this. Here's an example from the angular integration demo (which is the Flowchart Builder application converted to use Angular):
var app = angular.module('app', ['$jsPlumb']);
...
...
app.directive('question', function (jsPlumbFactory) {
return jsPlumbFactory.node({
inherit:["removeNode", "editNode"],
templateUrl: "question_template.tpl",
link:function(scope, element) {
element.addClass("flowchart-object flowchart-question");
}
});
});
The key here is the call to jsPlumbFactory.node
. This method takes care of setting everything you need; you provide the URL of the template to use and optionally a link
function. You'll also notice a parameter called inherit
in this example - this is discussed below.
templateUrl
You cannot provide an inline template; your templates must be declared somewhere in your HTML.
link
A link
function is not required, but can be provided if you wish. In the Toolkit's Angular demo, the link function is used to get around the fact that when the Toolkit renders Nodes via Angular, there is no declarative way of setting attributes (such as the class name) on that directive's root element. So in this link function you can see we retroactively set a couple of classes on the Node's root element.
inherit
This concept is not a core Angular concept. It is a helper that enables you to declare items from your Controller's scope that you wish to have in your Node's scope. The mechanism used by the Toolkit, out of necessity, creates an isolated scope for each Node. The inherit
mechanism will pull named items out of the isolated scope's ancestors and copy them in to the isolate scope itself. In the Toolkit's Angular example, removeNode
and editNode
are functions declared in the controller's scope that all Nodes need to have access to.
Accessing Toolkit/Surface instances
To access instances of the Toolkit or of the Surface widget, you can use the jsPlumbService
:
app.controller("FooController", [ "jsPlumbService", function(jsPlumbService) {
var toolkit = jsPlumbService.getToolkit("myToolkit");
var surface = jsPlumbService.getSurface("mySurface");
}]);
Resetting a Toolkit instance
Should you wish to clear a Toolkit instance (this is not the same as the Toolkit's own clear
method: this is for clearing a Toolkit reference out from the service, so that subsequent requests for the Toolkit with the given ID will cause a new Toolkit to be created), you can make this call:
Binding Events
To bind to an event on a Toolkit, which may or may not yet exist, you can use the service's bind
method:
app.controller("FooController", [ "jsPlumbService", function(jsPlumbService) {
jsPlumbService.bind("ready", "myToolkit", function() {
alert("The toolkit is ready");
});
}]);
In most cases when you try to bind to a Toolkit it will have been created. In the above example it may well not have been; in general you can use this method for safety if you haven't yet got a concrete handle on the Toolkit instance you want.
If you're using Ports in your application there's a limitation with the template engine you need to be aware of. When a Node is rendered, using a directive, Angular has not yet bound the data to the DOM. This means that if you had a template like this, say:
The data-id
attribute would not have a value immediately after rendering. In most cases this is not a problem, but say you have this:
<div>
<h1>Hello</h1>
<jtk-port ng-repeat="port in node.ports" port-id="{{port.id}}" port-type="default"/>
</div>
This is more of a problem, since the value of the port-id
attribute is used by jsPlumb to wire up the UI to the data model. In this case, that value will be "{{port.id}}"
, for every Port. There does not seem to be a way around this using templating alone. In this case, you need to add the Ports after the fact, in the nodeAdded
event of your render parameters: