I have a view component to create a responsive image. The Invoke signature is as follows:
public IViewComponentResult Invoke(string imageUrl, string alt, bool lazyLoad, string cssClass, string deferClassName)
I have all the tag helpers registered in _ViewImports. Cleared bin and obj folders, restarted, cleaned and rebuilt.
I've added all params when calling the view component.
I did however notice though that intellisense only picks it up when I add a second parameter:
The same thing happens if alt is the param I add to the view component.
Anyway, either way the view component doesn't render and my breakpoint in the Invoke method isn't hit during debugging.
I'm using .net-core 6.0 and VS2022
ANSWER: I was passing the bool param as a string
Related
Is there a way to detect which node is being rendered when the user selects a link within the pages detail app and only the iframe changes? If just the the iframe is changing I need a mechanism that can call the parent page and send the path of the node that is being rendered in the iframe. We run Magnolia EE 5.6.11.
My issue is that I have a ValueChangeListener in a ComboBox that I use as a versionSelector in a PageBar extension in the pages detail app.
// Create a selection component;
private ComboBox versionSelector = new ComboBox();
private Listener listener;
private boolean isSettingValue;
public VersionSelectorViewImpl(){
construct();
}
private void construct() {
versionSelector.setVisible(false);
versionSelector.setSizeUndefined();
versionSelector.setImmediate(true);
versionSelector.setNullSelectionAllowed(false);
versionSelector.setTextInputAllowed(false);
//setup listener for the selected item
versionSelector.addValueChangeListener(new Property.ValueChangeListener() {
#Override
public void valueChange(Property.ValueChangeEvent event) {
if (listener != null) {
listener.versionSelected((Object) event.getProperty().getValue());
}
}
});
}
The implementation is similar to the LanguageSelector or VariantSelector. When someone activates a hyperlink in the page template the iframe changes and the valueChange method retrieves the wrong value (ie. the event is from the previous page).
When someone activates a link, the PagesEditorSubApp#updateNodePath calls the updateLocationDependentComponents which calls the PageBar.onLocationUpdate. This calls in our case the VersionSelector#setCurrentVersion method. At this point I would need to reload the page detail subapp so that the listener is correctly set to the new page. I tried using the pageEditorPresenter.refresh() method in the setCurrentVersion method but it didn't do it.
In Magnolia 5.x you need to fire ContentChangeEvent to trigger the refresh (and hope that subapp you want to refresh listens to it, which in case of page detail subapp shouldn't be a problem).
Or, since you mention LanguageSelector, you can indeed try to call PageEditorPresenter directly as it does from info.magnolia.pages.app.editor.pagebar.languageselector.LanguageSelector#languageSelected, tho unless you need to modify something in the presenter (eg. locale in the example above), it seems rather unnecessary coupling of the code.
Once you are migrating your code to Magnolia 6.x and new UI framework, you have more convenient way of triggering notification of datasource change which all the views consuming data from given source listen to and facilitating refresh that way (as is shown eg in PasteComponentAction here.
I'm new to Prism with Xamarin.Forms. I've implemented the ViewModel approach using the Navigation and Commanding classes. It works just fine but there's just one thing I don't understand. With the AutowireViewModel set to true the ViewModelLocator automatically fills the BindingContext for me and that is sweet. The order of things is not what I expected. First the binding for the properties on the View fire and then the OnNavigatedTo is fired. This means that my init of the properties is already finished by the time I receive the parameters on the View. I can solve this by executing the RaisePropertyChanged. This causes the following:
I'm forced to write RaisePropertyChanged for every property on the ViewModel I want to see on the view with the new Data.
All bindings fire two times. For fast stuff that's not a problem but some are slower.
Data is refreshed after the View has become visible. Not disturbing but it would be nicer to show the finished View with it's data all at once.
All properties must be able to handle null references.
Is there a way to initialize the data in the ViewModel before the binding kicks in?
Actually Prism for Xamarin.Forms has long supported initializing your ViewModels prior to the View being pushed onto the NavigationStack. That said there is an order of operations that has to be taken into consideration. We cannot for instance perform a bunch of operations on a ViewModel and then attach it to a View.
The Order in which things are carried out are as follows:
The View is Created (Anything in the View's ctor is executed)
If you have specifically attached the ViewModelLocator.AutowireViewModel property this will resolve the ViewModel as part of the ctor
If you have not specifically opted out of the ViewModelLocator's Autowire, the Navigation Service will set it for you (after the ctor has completed)
The NavigationService will then call IAutoInitialize/IInitialize/InitializeAsync (for Prism 7.2+... INavigatingAware.OnNavigatingTo in older versions of Prism)
The NavigationService will then push the Page onto the Navigation Stack (note that this may or may not be visible to the user as additional pages may have to be added first when deep linking)
The NavigationService will then call OnNavigatedFrom / OnNavigatedTo (this is where people often report seeing a visible delay due to binding updates.
For an overwhelming number of scenarios if you have correctly initialized your ViewModel this process works exactly as you need. If you have some edge case where you absolutely have to ensure the ViewModel is initialized before it is set then you will need to handle this manually.
public partial class ViewA : ContentPage, IInitialize
{
private ViewAViewModel ViewModel { get; }
public ViewA(ViewAViewModel viewModel)
{
ViewModel = viewModel;
// Explicitly Opt Out of Autowiring
ViewModelLocator.SetAutowireViewModel(this, false);
InitializeComponent();
}
public void Initialize(INavigationParameters parameters)
{
ViewModel.Initialize(parameters);
BindingContext = ViewModel;
}
}
In my UI5 application, I have an i18n.properties file with keys and values:
#XMSG:
qty=Quantity
And I'm using this property value in a dialog box as title
onUpdateDialog: function() {
var that = this;
var dialog = new Dialog({
title: "{i18n>qty}",
// ...,
});
dialog.open();
},
But when I run my application, the dialog box title is not getting displayed:
When I use text values from i18n property file somewhere else it's getting displayed.
ManagedObjects, that are created by the application code imperatively outside of the framework-managed features (Such creating an instance of sap.m.Dialog in a Controller code without using the API loadFragment), have to be added to the model delegation chain manually in order to make use of the propagated models.
In order to do so, add the created instance to the parent's <dependents> aggregation. E.g.:
this.getView().addDependent(myDialog); // myDialog is now aware of the "i18n" model
From API Reference:
Special aggregation dependents is connected to the lifecycle management and databinding, but not rendered automatically and can be used for popups or other dependent controls or elements. This allows the definition of popup controls in declarative views and enables propagation of model and context information to them.
In order to use texts in the controller you need to fetch the text first, like so:
this.getOwnerComponent().getModel("i18n").getResourceBundle().getText("qty")
this will be the dialog inside the dialog, so declare a that before the dialog and change this to that..
var that = this;
that.getOwnerComponent().getModel("i18n").getResourceBundle().getText("qty")
Hope this solves your issue..
At the point of opening the Dialog, it doesn't know the i18n model. You need to provide the model to the dialog by calling dialog.setModel(this.getModel('i18n'), 'i18n') before opening the dialog.
I am curious to know if it is possible to add a fragment to a view model:
return new ViewModel([]);
Returns my view to https://example.com/view
However is it possible to set this dynamically to add a fragment?
return new ViewModel("#fragment")
To return to https://example.com/view#fragment
The use case, have a js login/register view that is either https://example.com/view#login or https://example.com/view#register and want to return to the correct view...
EDIT
Obviously, this can be done using a re-direct, however, in the case of returning form errors, ViewModel needs to be used...
Not sure if this is possible to apply param to router, but you can alwas return redirectToRegister = true, and then write and execute JavaScript in view which will change view if True.
A fragment is a same document reference i.e. if the URL specification is used correctly #register and #login will refer to different elements in the same document.
The view model therefore should be returning the same html in both cases, and the fragment will be handled by the browser. To distinguish register and login pages instead use different paths in the URL.
I'm programming in Flex Builder Burrito for an mobile application.
I'm trying to get a variable from navigator.PopView()
and i found the following site: adobe View and ViewNavigator
On that page is written that you can get to an returnedObject:
The ViewNavigator will save this object internally, and the new view can access it from with the navigator.returnedObject property.
The problem is when I want to acces the returnedObject flash builder doesn't seem to find that even the package isn't found.
I've found my problem on an other site.
There it's plain simple explained.
Do the override public function createReturnObject():Object.
On the page where it needs to be send back.
Then on the popped view, you can acces it by returnedObject.
On same page next lines are
The property is a ViewReturnObject
which contains the object that was
returned
and the context in which the removed view was pushed (See Setting
the View Context).
ViewNavigator.poppedViewReturnedObject
is guaranteed to be set by the time
the new view
receives the add event and will be destroyed after the view receives its
viewActivate
event.
and also a NOTE
Note, the return object is only stored when a view is popped of
the navigation stack
or replaced through the use of the pop and replace navigation
operations (e.g.,
replaceView, popView, etc...). It will be cleared after the new view
receives its
ViewNavigatorEvent.VIEW_ACTIVATE event.
I think should try function to get popuped view poppedViewReturnedObject of ViewNavigator
Its description is also on same page
public function get poppedViewReturnedObject():ViewReturnObject
Hopes that help