Handling Model Navigation
Dealing with model changes
Section titled “Dealing with model changes”The lifecycle of your extension will vary based on user actions and your extension setup in the manifest.
| Window Type | Model Can Change |
|---|---|
| headless | ✅ |
| floating | ✅ |
| modal | ❌ |
| sidebar | ✅ |
| tab | ✅ |
Note that it’s possible for getActiveModel to throw an error in the case where there is no active model, for example
if a user on Desktop closes all of their models.
Note that these patterns are only a guide and can be used in conjunction with best practices if you are using a framework (Vue, React, Angular, etc.).
Stateless Pattern
Section titled “Stateless Pattern”Applicable when your extension comprises actions that can be performed on the model with no need to display update to date information to the user.
async function someAction() { // Always fetch the active model and perform the action // Pass this model through any nested functions to ensure data consistency. const model = await SketchUpApi.getActiveModel(); model.performOperation((op) => { // For convenience and consistency you can extract the model reference from the operation. op.createFace(op.model, [[0, 0, 0], [100, 0, 0], [100, 100, 0], [0, 100, 0]]); }, 'Created a face');}Stateful Refresh Pattern
Section titled “Stateful Refresh Pattern”Applicable for reporting style extensions where the reporting calculation is fairly expensive. The general idea is that you display an “update” button when the model changes.
// Could default to false if you process the model on extension startup.let needsUpdate = true;// You may only want to update this when you've processed this to capture the model revision when the display was changed.let model = await SketchUpApi.getActiveModel();SketchUpApi.observeActiveModel(async (modelMeta) => { model = await modelMeta.getModel(); if (modelMeta.isDifferentModel(model)) { // Perhaps you have special handling for an entirely new model } if (modelMeta.isModelChanged(model)) { // This branch will execute if the model is different OR the model revision has changed console.log(`Model revision ${modelMeta.revision}`) // You may do more complex logic here to determine this state needsUpdate = true; }});
async function processModel() { // Your extension application logic that extracts information from the model needsUpdate = false;}Alternatively you can use some sort of debouncing logic to delay the expensive work while rapid changes are being made to the model.
Stateful Reactive Pattern
Section titled “Stateful Reactive Pattern”Applicable for extensions that always need to display up-to-date information, or perform some sort of post-processing work.
let model = await SketchUpApi.getActiveModel();SketchUpApi.observeActiveModel(async (modelMeta) => { // You may not want to debounce this to account for rapid fire changes model = await modelMeta.getModel(); await processModel();});
async function processModel() { // Your extension application logic that extracts information from the model}