[doc] documented viewmodels and their callbacks and dependency injection for usage in plugins
This commit is contained in:
parent
c6a0ef2425
commit
c6fdab554b
5 changed files with 214 additions and 0 deletions
|
|
@ -3,6 +3,9 @@
|
|||
Concepts
|
||||
========
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
OctoPrint's plugins are `Python Packages <https://docs.python.org/2/tutorial/modules.html#packages>`_ which in their
|
||||
top-level module define a bunch of :ref:`control properties <sec-plugin-concepts-controlproperties>` defining
|
||||
metadata (like name, version etc of the plugin) as well as information on how to initialize the plugin and into what
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ Distributing your plugin
|
|||
|
||||
You can distribute a plugin with OctoPrint via two ways.
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
.. _sec-plugins-distribution-manual:
|
||||
|
||||
Manual file distribution
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
Getting Started
|
||||
===============
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Over the course of this little tutorial we'll build a full fledged, installable OctoPrint plugin that displays "Hello World!"
|
||||
at some locations throughout OctoPrint and also offers some other basic functionality to give you an idea of what
|
||||
you can achieve with OctoPrint's plugin system.
|
||||
|
|
|
|||
|
|
@ -12,3 +12,4 @@ Developing Plugins
|
|||
distributing.rst
|
||||
mixins.rst
|
||||
hooks.rst
|
||||
viewmodels.rst
|
||||
|
|
|
|||
204
docs/plugins/viewmodels.rst
Normal file
204
docs/plugins/viewmodels.rst
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
.. _sec-plugins-viewmodels:
|
||||
|
||||
Viewmodels
|
||||
==========
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
When implementing frontend components, you'll sooner or later want to define your own `KnockoutJS viewmodels <http://knockoutjs.com/>`_
|
||||
in order to provide custom functionality.
|
||||
|
||||
.. _sec-plugins-viewmodels-registering:
|
||||
|
||||
Registering custom viewmodels
|
||||
-----------------------------
|
||||
|
||||
Register your viewmodel with OctoPrint's web app by pushing a 3-tuple consisting of your viewmodel's class, a list
|
||||
of all required dependencies to be injected into the constructor and a list of all elements to bind the viewmodel to.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
$(function() {
|
||||
function MyCustomViewModel(parameters) {
|
||||
var self = this;
|
||||
|
||||
self.loginState = parameters[0]; // requested as first constructor parameter below
|
||||
|
||||
// more of your viewmodel's implementation
|
||||
}
|
||||
|
||||
OCTOPRINT_VIEWMODELS.push([
|
||||
MyCustomViewModel,
|
||||
["loginStateViewModel"],
|
||||
["#some_div", "#some_other_div"]
|
||||
]);
|
||||
})
|
||||
|
||||
.. note::
|
||||
|
||||
Each provided binding target may be either a string which will then be passed to jQuery's ``$(...)`` method to resolve
|
||||
the target, or alternatively directly a jQuery element.
|
||||
|
||||
.. _sec-plugins-viewmodels-dependencies:
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
OctoPrint will try to inject all viewmodel dependencies requested by your viewmodel. In order to do this it will
|
||||
perform multiple passes iterating over all registered viewmodels and collecting the necessary depedencies prior to
|
||||
construction. Circular depedencies (A dependens on B, B on C, C on A) naturally cannot be resolved and will cause an
|
||||
error to be logged to the Javascript console.
|
||||
|
||||
OctoPrint's core currently comes with the following viewmodels that your plugin can request for injection:
|
||||
|
||||
appearanceViewModel
|
||||
Viewmodel that holds the appearance settings (name, color and transparency flag).
|
||||
connectionViewModel
|
||||
Viewmodel for the connection sidebar entry.
|
||||
controlViewModel
|
||||
Viewmodel for the control tab.
|
||||
gcodeFilesViewModel
|
||||
Viewmodel for the files sidebar entry.
|
||||
firstRunViewModel
|
||||
Viewmodel for the first run dialog.
|
||||
gcodeViewModel
|
||||
Viewmodel for the gcode viewer tab.
|
||||
logViewModel
|
||||
Viewmodel for the logfile settings dialog.
|
||||
loginStateViewModel
|
||||
Viewmodel for the current loginstate of the user, very interesting for plugins that need to
|
||||
evaluate the current login state or information about the current user, e.g. associated roles.
|
||||
navigationViewModel
|
||||
Viewmodel for the navigation bar.
|
||||
printerProfilesViewModel
|
||||
Viewmodel for the printer profiles settings dialog.
|
||||
printerStateViewModel
|
||||
Viewmodel for the current printer state, very intersting for plugins that need
|
||||
to know information about the current print job, if the printer is connected, operational etc.
|
||||
settingsViewModel
|
||||
Viewmodel for the settings dialog, also holds all settings to be used by other viewmodels, hence
|
||||
very interesting for plugins as well.
|
||||
slicingViewModel
|
||||
Viewmodel for the slicing dialog.
|
||||
temperatureViewModel
|
||||
Viewmodel for the temperature tab, also holds current temperature information which
|
||||
might be interesting for plugins.
|
||||
terminalViewModel
|
||||
Viewmodel for the terminal tab, also holds terminal log entries.
|
||||
timelapseViewModel
|
||||
Viewmodel for the timelapse tab.
|
||||
usersViewModel
|
||||
Viewmodel for the user management in the settings dialog.
|
||||
userSettingsViewModel
|
||||
Viewmodel for settings associated with the currently logged in user, used for
|
||||
the user settings dialog.
|
||||
|
||||
Additionally each plugin's viewmodel will be added to the viewmodel map used for resolving dependencies as well, using
|
||||
the viewmodel's class name with a lower case first character as identifier (so "MyCustomViewModel" will be registered
|
||||
for dependency injection as "myCustomViewModel").
|
||||
|
||||
.. _sec-plugins-viewmodels-callbacks:
|
||||
|
||||
Callbacks
|
||||
---------
|
||||
|
||||
OctoPrint's web application will call several callbacks on all registered viewmodels, provided they implement them.
|
||||
Those are listed below:
|
||||
|
||||
onStartup()
|
||||
Called when the first initialization has been done: All viewmodels are constructed and hence their dependencies
|
||||
resolved, no bindings have been done yet.
|
||||
|
||||
onBeforeBinding()
|
||||
Called per viewmodel before attempting to bind it to its binding targets.
|
||||
|
||||
onAfterBinding()
|
||||
Called per viewmodel after binding it to its binding targets.
|
||||
|
||||
onAllBound(allViewModels)
|
||||
Called after all viewmodels have been bound, with the list of all viewmodels as the single parameter.
|
||||
|
||||
onStartupComplete()
|
||||
Called after the startup of the web app has been completed.
|
||||
|
||||
onServerDisconnect()
|
||||
Called if a disconnect from the server is detected.
|
||||
|
||||
onDataUpdaterReconnect()
|
||||
Called when the connection to the server has been reestablished after a disconnect.
|
||||
|
||||
fromHistoryData(data)
|
||||
Called when history data is received from the server. Usually that happens only after initial connect in order to
|
||||
transmit the temperature and terminal log history to the connecting client. Called with the ``data`` as single parameter.
|
||||
|
||||
fromCurrentData(data)
|
||||
Called when current printer status data is received from the server with the ``data`` as single parameter.
|
||||
|
||||
onSlicingProgress(slicer, modelPath, machineCodePath, progress)
|
||||
Called on slicing progress, call rate is once per percentage point of the progress at maximum.
|
||||
|
||||
onEvent<EventName>(payload)
|
||||
Called on firing of an event of type ``EventName``, e.g. ``onEventPrintDone``. See :ref:`the list of available events <sec-events-available_events>`
|
||||
for the possible events and their payloads.
|
||||
|
||||
fromTimelapseData(data)
|
||||
Called when timelapse configuration data is received from the server. Usually that happens after initial connect.
|
||||
|
||||
onDataUpdaterPluginMessage(plugin, message)
|
||||
Called when a plugin message is pushed from the server with the identifier of the calling plugin as first
|
||||
and the actual message as the second parameter. Note that the latter might be a full fledged object, depending
|
||||
on the plugin sending the message. You can use this method to asynchronously push data from your plugin's server
|
||||
component to it's frontend component.
|
||||
|
||||
onUserLoggedIn(user)
|
||||
Called when a user gets logged into the web app, either passively (upon initial load of the page due to a valid
|
||||
"Remember Me" cookie) or due to an active completion of the login dialog. The user data of the just logged in user
|
||||
will be provided as only parameter.
|
||||
|
||||
onUserLoggedOut()
|
||||
Called when a user gets logged out of the web app.
|
||||
|
||||
onTabChange(current, previous)
|
||||
Called before the main tab view switches to a new tab, so `before` the new tab becomes visible. Called with the
|
||||
current and previous tab's hash (e.g. ``#control``).
|
||||
|
||||
onAfterTabChange
|
||||
Called after the main tab view switches to a new tab, so `after` the new tab becomes visible. Called with the
|
||||
current and previous tab's hash (e.g. ``#control``).
|
||||
|
||||
In order to hook into any of those callbacks, just have your viewmodel define a function named accordingly, e.g.
|
||||
to get called after all viewmodels have been bound during application startup, implement a function ``onAllBound``
|
||||
on your viewmodel, taking a list of all bound viewmodels:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
$(function() {
|
||||
function MyCustomViewModel(parameters) {
|
||||
var self = this;
|
||||
|
||||
// ...
|
||||
|
||||
self.onAllBound = function(allViewModels) {
|
||||
// do something with them
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
OCTOPRINT_VIEWMODELS.push([
|
||||
MyCustomViewModel,
|
||||
["loginStateViewModel"],
|
||||
["#some_div", "#some_other_div"]
|
||||
]);
|
||||
})
|
||||
|
||||
.. seealso::
|
||||
|
||||
`OctoPrint's core viewmodels <https://github.com/foosel/OctoPrint/tree/devel/src/octoprint/static/js/app/viewmodels>`_
|
||||
OctoPrint's own viewmodels use the same mechanisms for interacting with each other and the web application as
|
||||
plugins. Their sourcecode is therefore a good point of reference on how to achieve certain things.
|
||||
`KnockoutJS documentation <http://knockoutjs.com/documentation/introduction.html>`_
|
||||
OctoPrint makes heavy use of KnockoutJS for building up its web app.
|
||||
Loading…
Reference in a new issue