Nativescript: We could have a directives loading control like Android does with FragmentTransaction

Created on 5 Jun 2018  路  10Comments  路  Source: NativeScript/NativeScript

I think NativeScript could have FragmentTransaction to build fragments (directives) on the screen. This feature will allows us to have more control about the "fragments" loading. I mean, the directives loading/lifecycle.

This is an Android fragment transaction.

Fragment01 fmt01 = Fragment01.newInstance(mSaleId);
Fragment02 fmt02 = Fragment02.newInstance(mSaleId);
Fragment03 fmt03 = Fragment03.newInstance(mSaleId);

FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.additions_container, fmt01, "fmt01");
transaction.add(R.id.additions_container, fmt02, "fmt02");
transaction.add(R.id.discounts_container, fmt03, "fmt03");
transaction.commit();

At the moment we make it using directives on template, right? but..

We don't have control about the "fragments" (directives) loading on the template.

android

Most helpful comment

@francisrod01 in Angular based applications you can use the Angular Change convetion for all exposed events. For example if you have a text property, you can create listener for textChange.

A POC application that you can use as a reference.

All 10 comments

@francisrod01 we do have the Frame API which is the core logic for navigation in NativeScript.

You can also control the loading event of each View/Element in NativeScript via the loaded event.

Thanks, @NickIliev!

Please, can you provide us an example to use it?

I'm not good at reading documentation and figuring out how to use and good practice of using the methods. I believe we can use loadedEvent as View.loadedEvent(string)... in a constructor().

@francisrod01 here is a very basic example

XML

<StackLayout loaded="onStackLoaded" />

TypeScript

import { EventData } from "tns-core-modules/data/observable";
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout"

export function onStackLoaded(args: EventData) {
    console.log(args);
    const myStack = <StackLayout>args.object;
}

or if you need ,you can create a code behind listener for any supported event

const myStack = <StackLayout>page.getViewById("myStackId");
myStack.on("loaded", (args) => {
    console.log("Stack Loaded")
});

const textField = <TextField>page.getViewById("myTextFieldId");
textField.on("textChange", (args) => {
    console.log(args.newValue);
})

That said there are also a set of application events that can be used as well.

Thanks, @NickIliev! I like this interesting implementation.
I'd like to use something like it with NativeScript/Angular.

@francisrod01 in Angular based applications you can use the Angular Change convetion for all exposed events. For example if you have a text property, you can create listener for textChange.

A POC application that you can use as a reference.

I like the "Components event lifecycles".
I appreciate it!

@NickIliev how can I do this in NS/Angular using Observable, model to set data to components like Android fragments.setArguments() does?

https://discourse.nativescript.org/t/where-do-i-start-from-im-new-to-nativescript/5770/10?u=francisrod01

@francisrod01 in ANgular use the Angular binding instead of data/observable. For example look at the string property here which is bound to the result from an HTTP response.

Let me know if we could do the same in a loop though Component.

I have a situation that the MainActivity populate a Tabs by getRooms() call and instantiate a TablesFragment in a for passing the roomId as a argument to the fragment instantiates your own tables.

I can explain this scenario with code:

In the MainActivity.java my Service calles mDataAccess.getRooms():

...
public void setRoomsTabs() {
    mDataAccess.getRooms(new DataAccessGetCollectionCallback<Room>() {
        @Override
        public void onSuccess(SparseArray<Room> rooms) {
            ViewPager viewPager = findViewById(R.id.viewpager);
            setupViewPager(viewPager, rooms);

            TabLayout tabLayout = findViewById(R.id.tabs);
            tabLayout.setupWithViewPager(viewPager);
        }
    });
}

And then calls setupViewPager(...) to loop the TablesFragment passing arguments.

...
private void setupViewPager(ViewPager viewPager, SparseArray<Room> rooms) {
    mAdapter = new Adapter(getSupportFragmentManager());

    for (int i = 0; i < rooms.size(); i++) {
        Room room = rooms.valueAt(i);

        Bundle bundle = new Bundle();
        bundle.putInt(ARGS_ROOM_ID, room.getId());

        TablesFragment fragment = new TablesFragment();
        fragment.setArguments(bundle);

        mAdapter.addFragment(fragment, room.getName());
    }
    viewPager.setAdapter(mAdapter);
}

Inside the TablesFragment.java my Service calles getTables() and

onCreate(...) {
...
Bundle bundle = this.getArguments();
mRoomId = bundle.getInt(ARGS_ROOM_ID);

mAdapter = new RecyclerViewAdapter(mListener);

mDataAccess = DataAccess.getInstance();

mDataAccess.getTables(new DataAccessGetCollectionCallback<Table>() {
    @Override
    public void onSuccess(SparseArray<Table> tables) {
        onTablesUpdate(tables);
    }
});

...

public void onTablesUpdate(SparseArray<Table> tables) {
    for (int i = 0; i < tables.size(); i++) {
        Table table = tables.valueAt(i);
        if (table.getRoomId() == mRoomId) {
            mAdapter.updateTable(table);
        }
    }
}

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings