Skip to content

Migrating from 0.9.0 to 1.0.0

mvindahl edited this page Aug 17, 2014 · 3 revisions

The API is published in a different way now

The method by which the <panzoom> directive publishes its API has changed from version 0.9.0 to version 1.0.0. This is a breaking change which will impact your code if you either use the directive or if you have written custom UI which triggers calls to any of the API methods (that is, zoomIn(), zoomOut(), changeZoomLevel(), zoomToFit(), getViewPosition(), or getModelPosition()).

To sum it up, the 0.9.0 way of publishing the API was to let the <panzoom> directive attach methods to the model object which it was passed. These methods could then be invoked by anyone holding a reference to the model object. It was a quick, dirty, and very non-angular way to expose the API.

From 1.0.0 and going forward, the API is instead published by <panzoom> directive to a registry maintained by PanZoomService using the id of the <panzoom> directive as the key. Any client code with knowledge of the key can subsequently request the API. This is in line with the angular philosophy that shared state should live in a service layer and that models are intended for state, not methods.

Migration guide

In general, it should not be too difficult to migrate. The scenarios described below should cover most cases:

Self contained Panzoom directive, no other UI affecting it

I suspect that this is a rare case, but anyway. The <panzoom> directive is declared and works as such but neither the <panzoomwidget> directive nor any custom UI is used to control it from the outside.

In this case, the HTML remains unchanged:

<panzoom config="panzoomConfig" model="panzoomModel">
    <!-- contents -->
</panzoom>

Panzoom directive controlled by Panzoomwidget directive

Both a <panzoom> directive and a <panzoomwidget> directive is declared.

In 0.9.0, the two directives would be linked implicitly through their shared model and the fact that the <panzoom> directive would attach methods to that model:

<panzoom config="panzoomConfig" model="panzoomModel">
    <!-- contents -->
</panzoom>
<panzoomwidget config="panzoomConfig" model="panzoomModel"></panzoomwidget>

In 1.0.0+, this should be rewritten as:

<panzoom id="MyPanzoomId" config="panzoomConfig" model="panzoomModel">
    <!-- contents -->
</panzoom>
<panzoomwidget panzoom-id="MyPanZoomId"></panzoomwidget>

The main changes being that the <panzoom> directive now needs an id attribute in order to publish its API and the <panzoomwidget> directive now defines a panzoom-id attribute which explicitly links it to a <panzoom> directive. Also, since the <panzoom> directive now publishes its modal and config objects alongside the API, the <panzoomwidget> no longer requires these to be passed.

Panzoom directive controlled by custom UI/Javascript

This will cover both the case where you wrote a directive to replace the <panzoomwidget> and the case where you access the API from the enclosing controller.

In 0.9.0 you would declare:

<panzoom config="panzoomConfig" model="panzoomModel">
    <!-- contents -->
</panzoom>

Then, from your Javascript you would do something like this:

$scope.panzoomModel.zoomIn();

In 1.0.0+ you would need to declare an id attribute on the <panzoom> directive:

<panzoom id="MyPanzoomId" config="panzoomConfig" model="panzoomModel">
    <!-- contents -->
</panzoom>

In your Javascript you need to obtain the PanZoomService from dependency injection and get the API from this:

PanZoomService.getAPI(panzoomId).then(function (api) {
    api.zoomIn();
}

It's up to you if you wrap every API call in a PanZoomService.getAPI() call or if you just wrap it around your controller code for convenience. The <panzoomwidget> directive does the latter.

Technical note: In case you wonder why the getAPI() method returns a promise and not simply the API, consider that there is no guarantee that the API has been published at the time that it is requested; i.e. your code snippet may be executed before the <panzoom> directive has been linked.