Skip to content
Manuel Mauky edited this page Jan 18, 2016 · 20 revisions

This feature is currently beta and will be part of version 1.5.0.

What are Scopes in mvvmFX?

A Scope in mvvmFX is a data context between ViewModels. They are used to decouple dependant ViewModels from each other.

Types of Scopes

There are two types of Scopes:

  • Global scopes which are Singletons, which can be used with the @InjectViewModel Annotation
  • Scopes that are related to an ID

###API - Use @Inject or the ScopeStore

public class SomeViewModel1 implements ViewModel {

	//Global Instance of the Scope-type will be injected 
	//-> it doesn't matter in which ViewModel you do this -> you'll get the same instance	
	@InjectScope
	private TestScope scope1;

	//gets a scope for this ID. If it already exists in the storage you get it,
	@InjectScope("coolId2")
	private TestScope scope2;

	PersonMasterViewModel(){
            scope1.myScopeStringProperty((b,oldValue,newValue)->System.out.println(newValue));
            scope2.myScopeBooleanProperty((b,oldValue,newValue)->System.out.println(newValue));
	}
public class SomeViewModel2 implements ViewModel {
	private TestScope scope1;
	private TestScope scope2;

	PersonMasterViewModel(){
                //Global Instance of the Scope-type will returned 
		scope1 = ScopeStorage.get(TestScope.class);

                //returns the scope for this ID
		scope2 = ScopeStorage.get(TestScope.class, "cooldId2");
		
		//The property changes will cause a Syso in SomeViewModel1
		scope1.myScopeStringProperty().set("Communicate to other ViewModels");
		scope2.myScopeBooleanProperty().set(true); 
	}

#Examples

A good example are Master/Detail Views where you have ViewModels for Master and Detail. In this case you have to transport the information of the current selection from the Master-ViewModel to the Detail-ViewModel.

public class PersonMasterDetailScope implements Scope {
	public ObjectProperty<Person> displayedPerson = new SimpleObjectProperty<>();
	//Some logic which sets the displayed person - for example when the user chooses an element in the master list
	...
}
public class PersonMasterViewModel implements ViewModel {
	
	@InjectScope
	private TestScope scope;

	ObjectProperty<Person> selectedPerson = new SimpleObjectProperty<>();

	public ScopedViewModelA() {
		...
		scope.displayedPerson.bind(selectedPerson);
		...
	}	
}
public class PersonDetailViewModel implements ViewModel {
	
	@InjectScope
	private TestScope scope;

	public ScopedViewModelB() {      
		scope.displayedPerson.addListener((b,o,newSelectedPerson)->initViewModelWithPerson(newSelectedPerson));
	}	
}